diff options
359 files changed, 7603 insertions, 2441 deletions
@@ -173,11 +173,14 @@ sunos5-v9 \ sunos5-v9-static \ sunos5-v9-cc-g++ \ ultrix-gcc: - @ if test -f configs/current || test -L configs/current ; then \ - echo "Please run 'make realclean' before changing configs" ; \ - exit 1 ; \ + @ if test -f configs/current -o -L configs/current; then \ + if ! cmp configs/$@ configs/current > /dev/null; then \ + echo "Please run 'make realclean' before changing configs" ; \ + exit 1 ; \ + fi ; \ + else \ + cd configs && rm -f current && ln -s $@ current ; \ fi - (cd configs && rm -f current && ln -s $@ current) $(MAKE) default diff --git a/SConstruct b/SConstruct index 964af7e591..ea63b90f46 100644 --- a/SConstruct +++ b/SConstruct @@ -225,9 +225,10 @@ SConscript( duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html ) -if 'progs' in COMMAND_LINE_TARGETS: - SConscript( - 'progs/SConscript', - variant_dir = os.path.join('progs', env['build']), - duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html - ) +env.Default('src') + +SConscript( + 'progs/SConscript', + variant_dir = os.path.join('progs', env['build']), + duplicate = 0 # http://www.scons.org/doc/0.97/HTML/scons-user/x2261.html +) diff --git a/configs/linux-cell b/configs/linux-cell index 229ac73d6d..e89a08cd93 100644 --- a/configs/linux-cell +++ b/configs/linux-cell @@ -25,12 +25,16 @@ OPT_FLAGS = -O3 SDK = /opt/cell/sdk/usr -CFLAGS = $(OPT_FLAGS) -mcpu=cell -Wall -Winline -Wmissing-prototypes \ - -fPIC -m32 -std=c99 -mabi=altivec -maltivec \ + +COMMON_C_CPP_FLAGS = $(OPT_FLAGS) -Wall -Winline \ + -fPIC -m32 -mabi=altivec -maltivec \ -I. -I$(SDK)/include \ -DGALLIUM_CELL $(DEFINES) -CXXFLAGS = $(CFLAGS) +CFLAGS = $(COMMON_C_CPP_FLAGS) -Wmissing-prototypes -std=c99 + +CXXFLAGS = $(COMMON_C_CPP_FLAGS) + # Omitting glw here: SRC_DIRS = glsl mesa gallium gallium/winsys glu glut/glx glew diff --git a/configure.ac b/configure.ac index 27405bbc24..be06adf5e5 100644 --- a/configure.ac +++ b/configure.ac @@ -20,7 +20,7 @@ AC_CANONICAL_HOST dnl Versions for external dependencies LIBDRM_REQUIRED=2.4.15 LIBDRM_RADEON_REQUIRED=2.4.17 -DRI2PROTO_REQUIRED=2.2 +DRI2PROTO_REQUIRED=2.1 GLPROTO_REQUIRED=1.4.11 dnl Check for progs diff --git a/docs/egl.html b/docs/egl.html index 844cc32079..82cc06600b 100644 --- a/docs/egl.html +++ b/docs/egl.html @@ -302,10 +302,18 @@ pbuffer surfaces. Therefore, the driver is responsible to guarantee that the client API renders to the specified render buffer for pixmap and pbuffer surfaces.</p> +<h3><code>EGLDisplay</code> Mutex</h3> + +The <code>EGLDisplay</code> will be locked before calling any of the dispatch +functions (well, except for GetProcAddress which does not take an +<code>EGLDisplay</code>). This guarantees that the same dispatch function will +not be called with the sample display at the same time. If a driver has access +to an <code>EGLDisplay</code> without going through the EGL APIs, the driver +should as well lock the display before using it. + <h3>TODOs</h3> <ul> -<li>Thread safety</li> <li>Pass the conformance tests</li> <li>Better automatic driver selection: <code>EGL_DISPLAY</code> loads all drivers and might eat too much memory.</li> diff --git a/docs/relnotes-7.7.1.html b/docs/relnotes-7.7.1.html index 959efd9e57..c3d42c1d54 100644 --- a/docs/relnotes-7.7.1.html +++ b/docs/relnotes-7.7.1.html @@ -44,6 +44,7 @@ tbd <li>Fixed mipmap generation bug caused by invalid viewport state. <li>Gallium SSE codegen for XPD didn't always work. <li>Fixed Windows build. +<li>Fixed broken glMultiDrawElements(). </ul> diff --git a/docs/relnotes-7.8.html b/docs/relnotes-7.8.html index 7510139ccd..177d11e57a 100644 --- a/docs/relnotes-7.8.html +++ b/docs/relnotes-7.8.html @@ -36,6 +36,7 @@ tbd <ul> <li>GL_NV_conditional_render extension (swrast driver only) <li>GL_EXT_draw_buffers2 extension (swrast and i965 driver only) +<li>GL_ARB_fragment_coord_conventions extension (for swrast and Gallium drivers) <li>Much improved support for <a href="egl.html">EGL in Mesa</a> <li>New state trackers for <a href="opengles.html">OpenGL ES 1.1 and 2.0</a> <li>Dedicated documentation for Gallium diff --git a/include/GL/internal/dri_interface.h b/include/GL/internal/dri_interface.h index 58540d6005..cb99c270f5 100644 --- a/include/GL/internal/dri_interface.h +++ b/include/GL/internal/dri_interface.h @@ -269,22 +269,20 @@ struct __DRItexBufferExtensionRec { * Used by drivers that implement DRI2 */ #define __DRI2_FLUSH "DRI2_Flush" -#define __DRI2_FLUSH_VERSION 2 +#define __DRI2_FLUSH_VERSION 3 struct __DRI2flushExtensionRec { __DRIextension base; void (*flush)(__DRIdrawable *drawable); /** - * Flush all rendering queue in the driver to the drm and - * invalidate all buffers. The driver will call out to - * getBuffers/getBuffersWithFormat before it starts rendering - * again. + * Ask the driver to call getBuffers/getBuffersWithFormat before + * it starts rendering again. * - * \param drawable the drawable to flush and invalidate + * \param drawable the drawable to invalidate * - * \since 2 + * \since 3 */ - void (*flushInvalidate)(__DRIdrawable *drawable); + void (*invalidate)(__DRIdrawable *drawable); }; diff --git a/progs/demos/fslight.c b/progs/demos/fslight.c index 395b7caa2c..91a5a80132 100644 --- a/progs/demos/fslight.c +++ b/progs/demos/fslight.c @@ -467,8 +467,8 @@ Init(void) const char *version; version = (const char *) glGetString(GL_VERSION); - if (version[0] != '2' || version[1] != '.') { - printf("This program requires OpenGL 2.x, found %s\n", version); + if (version[0] == '1') { + printf("This program requires OpenGL 2.x or higher, found %s\n", version); exit(1); } diff --git a/progs/es1/.gitignore b/progs/es1/.gitignore index 4f1427531a..5e29a6b5fa 100644 --- a/progs/es1/.gitignore +++ b/progs/es1/.gitignore @@ -1,5 +1,6 @@ screen/gears screen/tri +xegl/bindtex xegl/drawtex xegl/es1_info xegl/msaa diff --git a/progs/fp/fp-tri.c b/progs/fp/fp-tri.c index 70676d4c40..e45a799a00 100644 --- a/progs/fp/fp-tri.c +++ b/progs/fp/fp-tri.c @@ -188,6 +188,7 @@ static void Init( void ) } glClearColor(.1, .3, .5, 0); + fclose(f); } static void Reshape(int width, int height) diff --git a/src/gallium/state_trackers/python/retrace/README b/progs/gallium/python/retrace/README index 822cd11404..822cd11404 100644 --- a/src/gallium/state_trackers/python/retrace/README +++ b/progs/gallium/python/retrace/README diff --git a/src/gallium/state_trackers/python/retrace/format.py b/progs/gallium/python/retrace/format.py index a4285bfe07..a4285bfe07 100755 --- a/src/gallium/state_trackers/python/retrace/format.py +++ b/progs/gallium/python/retrace/format.py diff --git a/src/gallium/state_trackers/python/retrace/interpreter.py b/progs/gallium/python/retrace/interpreter.py index 190db43b08..2db71a212f 100755 --- a/src/gallium/state_trackers/python/retrace/interpreter.py +++ b/progs/gallium/python/retrace/interpreter.py @@ -272,6 +272,10 @@ class Screen(Object): def get_paramf(self, param): pass + def context_create(self): + context = self.real.context_create() + return Context(self.interpreter, context) + def is_format_supported(self, format, target, tex_usage, geom_flags): return self.real.is_format_supported(format, target, tex_usage, geom_flags) @@ -372,6 +376,9 @@ class Context(Object): pass def create_blend_state(self, state): + if isinstance(state, str): + state = gallium.Blend(state) + sys.stdout.write('\t%s\n' % state) return state def bind_blend_state(self, state): @@ -430,12 +437,15 @@ class Context(Object): def delete_fs_state(self, state): pass - + delete_vs_state = delete_fs_state - + def set_blend_color(self, state): self.real.set_blend_color(state) + def set_stencil_ref(self, state): + self.real.set_stencil_ref(state) + def set_clip_state(self, state): _state = gallium.Clip() _state.nr = state.nr diff --git a/src/gallium/state_trackers/python/retrace/model.py b/progs/gallium/python/retrace/model.py index d4a079fb1e..d4a079fb1e 100755 --- a/src/gallium/state_trackers/python/retrace/model.py +++ b/progs/gallium/python/retrace/model.py diff --git a/src/gallium/state_trackers/python/retrace/parse.py b/progs/gallium/python/retrace/parse.py index b08d368671..b08d368671 100755 --- a/src/gallium/state_trackers/python/retrace/parse.py +++ b/progs/gallium/python/retrace/parse.py diff --git a/src/gallium/state_trackers/python/retrace/parser.py b/progs/gallium/python/retrace/parser.py index bd47c9a6b0..bd47c9a6b0 100755 --- a/src/gallium/state_trackers/python/retrace/parser.py +++ b/progs/gallium/python/retrace/parser.py diff --git a/src/gallium/state_trackers/python/samples/gs.py b/progs/gallium/python/samples/gs.py index cd68abac9a..cd68abac9a 100644 --- a/src/gallium/state_trackers/python/samples/gs.py +++ b/progs/gallium/python/samples/gs.py diff --git a/src/gallium/state_trackers/python/samples/tri.py b/progs/gallium/python/samples/tri.py index f0b5e3dc98..f0b5e3dc98 100644 --- a/src/gallium/state_trackers/python/samples/tri.py +++ b/progs/gallium/python/samples/tri.py diff --git a/src/gallium/state_trackers/python/tests/.gitignore b/progs/gallium/python/tests/.gitignore index 0dbbaeea16..0dbbaeea16 100644 --- a/src/gallium/state_trackers/python/tests/.gitignore +++ b/progs/gallium/python/tests/.gitignore diff --git a/src/gallium/state_trackers/python/tests/base.py b/progs/gallium/python/tests/base.py index b022d073fd..b022d073fd 100755 --- a/src/gallium/state_trackers/python/tests/base.py +++ b/progs/gallium/python/tests/base.py diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore b/progs/gallium/python/tests/regress/fragment-shader/.gitignore index e33609d251..e33609d251 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/.gitignore +++ b/progs/gallium/python/tests/regress/fragment-shader/.gitignore diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-abs.sh index 103d7497f4..103d7497f4 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-abs.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-abs.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-add.sh index bcb9420596..bcb9420596 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-add.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-add.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-cb-1d.sh index 85fb9ea4e7..85fb9ea4e7 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-1d.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-cb-1d.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-cb-2d.sh index f70a5146f4..f70a5146f4 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-cb-2d.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-cb-2d.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-dp3.sh index b5281975d4..b5281975d4 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp3.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-dp3.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-dp4.sh index d59df76e70..d59df76e70 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dp4.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-dp4.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-dst.sh index fbb20fa9f6..fbb20fa9f6 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-dst.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-dst.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-ex2.sh index b511288f4b..b511288f4b 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-ex2.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-ex2.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-flr.sh index 99a2f96103..99a2f96103 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-flr.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-flr.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-frc.sh index a54c2623b0..a54c2623b0 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-frc.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-frc.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-lg2.sh index 5f5b4be109..5f5b4be109 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lg2.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-lg2.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-lit.sh index 6323c4712d..6323c4712d 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lit.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-lit.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-lrp.sh index 740809d22e..740809d22e 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-lrp.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-lrp.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-mad.sh index 413b9dc391..413b9dc391 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mad.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-mad.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-max.sh index b69f213261..b69f213261 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-max.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-max.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-min.sh index df284f49e7..df284f49e7 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-min.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-min.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-mov.sh index 64af72f381..64af72f381 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mov.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-mov.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-mul.sh index bdd0b0026b..bdd0b0026b 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-mul.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-mul.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-rcp.sh index f4b611b26a..f4b611b26a 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rcp.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-rcp.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-rsq.sh index d1e9b0b53b..d1e9b0b53b 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-rsq.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-rsq.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-sge.sh index 1f33fac472..1f33fac472 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sge.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-sge.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-slt.sh index d58b7886a1..d58b7886a1 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-slt.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-slt.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-abs.sh index ecd19248c6..ecd19248c6 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-abs.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-abs.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh index c2d99ddd15..c2d99ddd15 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-absneg.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-neg.sh index a08ab6d2dc..a08ab6d2dc 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-neg.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-neg.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-swz.sh index 6110647d97..6110647d97 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-srcmod-swz.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-srcmod-swz.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-sub.sh index 673fca139a..673fca139a 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-sub.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-sub.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh b/progs/gallium/python/tests/regress/fragment-shader/frag-xpd.sh index 6ec8b1184c..6ec8b1184c 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/frag-xpd.sh +++ b/progs/gallium/python/tests/regress/fragment-shader/frag-xpd.sh diff --git a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py b/progs/gallium/python/tests/regress/fragment-shader/fragment-shader.py index 41dd69d254..41dd69d254 100644 --- a/src/gallium/state_trackers/python/tests/regress/fragment-shader/fragment-shader.py +++ b/progs/gallium/python/tests/regress/fragment-shader/fragment-shader.py diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore b/progs/gallium/python/tests/regress/vertex-shader/.gitignore index e33609d251..e33609d251 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/.gitignore +++ b/progs/gallium/python/tests/regress/vertex-shader/.gitignore diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-abs.sh index 79c9ca69fb..79c9ca69fb 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-abs.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-abs.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-add.sh index ca97ad05df..ca97ad05df 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-add.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-add.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-arl.sh index 321140e89e..321140e89e 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arl.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-arl.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-arr.sh index d60ea46b36..d60ea46b36 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-arr.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-arr.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-cb-1d.sh index b41fe5dd38..b41fe5dd38 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-1d.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-cb-1d.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-cb-2d.sh index 45f5e6b729..45f5e6b729 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-cb-2d.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-cb-2d.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-dp3.sh index caff622fe6..caff622fe6 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp3.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-dp3.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-dp4.sh index 3dd2fd1c2f..3dd2fd1c2f 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dp4.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-dp4.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-dst.sh index da9cc18dfc..da9cc18dfc 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-dst.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-dst.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-ex2.sh index 4637227e5c..4637227e5c 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-ex2.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-ex2.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-flr.sh index aa80d6e394..aa80d6e394 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-flr.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-flr.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-frc.sh index 64d1a494e1..64d1a494e1 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-frc.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-frc.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-lg2.sh index 5cf16fd1aa..5cf16fd1aa 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lg2.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-lg2.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-lit.sh index a4a752d4d2..a4a752d4d2 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lit.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-lit.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-lrp.sh index 4bb5f3ec3f..4bb5f3ec3f 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-lrp.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-lrp.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-mad.sh index daaa941f15..daaa941f15 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mad.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-mad.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-max.sh index af279ec7f4..af279ec7f4 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-max.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-max.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-min.sh index 46d886c55b..46d886c55b 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-min.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-min.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-mov.sh index 0ef91637e0..0ef91637e0 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mov.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-mov.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-mul.sh index d34f6cd6e3..d34f6cd6e3 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-mul.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-mul.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-rcp.sh index cfb3ec37dc..cfb3ec37dc 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rcp.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-rcp.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-rsq.sh index faf1e6e7d4..faf1e6e7d4 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-rsq.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-rsq.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-sge.sh index 6de1d071ef..6de1d071ef 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sge.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-sge.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-slt.sh index 9a52422984..9a52422984 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-slt.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-slt.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-abs.sh index dc87ce4ae7..dc87ce4ae7 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-abs.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-abs.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh index d82eb08fd3..d82eb08fd3 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-absneg.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-neg.sh index e39bebcd9f..e39bebcd9f 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-neg.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-neg.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-swz.sh index 6f20552f21..6f20552f21 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-srcmod-swz.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-srcmod-swz.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-sub.sh index 0f9678b8a3..0f9678b8a3 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-sub.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-sub.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh b/progs/gallium/python/tests/regress/vertex-shader/vert-xpd.sh index 39d42ae2a0..39d42ae2a0 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vert-xpd.sh +++ b/progs/gallium/python/tests/regress/vertex-shader/vert-xpd.sh diff --git a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py b/progs/gallium/python/tests/regress/vertex-shader/vertex-shader.py index 2c44f872e1..2c44f872e1 100644 --- a/src/gallium/state_trackers/python/tests/regress/vertex-shader/vertex-shader.py +++ b/progs/gallium/python/tests/regress/vertex-shader/vertex-shader.py diff --git a/src/gallium/state_trackers/python/tests/surface_copy.py b/progs/gallium/python/tests/surface_copy.py index df5babb78a..df5babb78a 100755 --- a/src/gallium/state_trackers/python/tests/surface_copy.py +++ b/progs/gallium/python/tests/surface_copy.py diff --git a/src/gallium/state_trackers/python/tests/texture_render.py b/progs/gallium/python/tests/texture_render.py index 0fac1ea5ef..0fac1ea5ef 100755 --- a/src/gallium/state_trackers/python/tests/texture_render.py +++ b/progs/gallium/python/tests/texture_render.py diff --git a/src/gallium/state_trackers/python/tests/texture_sample.py b/progs/gallium/python/tests/texture_sample.py index db32b537a1..db32b537a1 100755 --- a/src/gallium/state_trackers/python/tests/texture_sample.py +++ b/progs/gallium/python/tests/texture_sample.py diff --git a/src/gallium/state_trackers/python/tests/texture_transfer.py b/progs/gallium/python/tests/texture_transfer.py index 35daca9e49..35daca9e49 100755 --- a/src/gallium/state_trackers/python/tests/texture_transfer.py +++ b/progs/gallium/python/tests/texture_transfer.py diff --git a/src/gallium/state_trackers/python/tests/tree.py b/progs/gallium/python/tests/tree.py index 0c1bcda4cf..0c1bcda4cf 100755 --- a/src/gallium/state_trackers/python/tests/tree.py +++ b/progs/gallium/python/tests/tree.py diff --git a/progs/objviewer/glm.c b/progs/objviewer/glm.c index 7f36cdf28e..7c964e489d 100644 --- a/progs/objviewer/glm.c +++ b/progs/objviewer/glm.c @@ -421,6 +421,7 @@ _glmReadMTL(GLMmodel* model, char* name) break; } } + fclose(file); } @@ -475,6 +476,7 @@ _glmWriteMTL(GLMmodel* model, char* modelpath, char* mtllibname) fprintf(file, "Ns %f\n", material->shininess); fprintf(file, "\n"); } + fclose(file); } diff --git a/progs/openvg/.gitignore b/progs/openvg/.gitignore new file mode 100644 index 0000000000..9b05e1e81d --- /dev/null +++ b/progs/openvg/.gitignore @@ -0,0 +1,24 @@ +demos/lion +demos/sp +trivial/arc +trivial/cap +trivial/clear +trivial/coord +trivial/dash +trivial/ellipse +trivial/filter +trivial/gradorigin +trivial/lineto +trivial/lingrad +trivial/lookup +trivial/mask4 +trivial/mask +trivial/path3 +trivial/radialgrad +trivial/readpixels +trivial/roundedrect +trivial/star-nonzero +trivial/star-oddeven +trivial/stroke2 +trivial/stroke +trivial/vguarc diff --git a/progs/redbook/Makefile b/progs/redbook/Makefile index 0ba5fbbb98..b41e488729 100644 --- a/progs/redbook/Makefile +++ b/progs/redbook/Makefile @@ -7,16 +7,84 @@ INCDIR = $(TOP)/include LIB_DEP = $(TOP)/$(LIB_DIR)/$(GL_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLU_LIB_NAME) $(TOP)/$(LIB_DIR)/$(GLUT_LIB_NAME) -LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) - -PROGS = aaindex aapoly aargb accanti accpersp alpha alpha3D anti \ - bezcurve bezmesh checker clip colormat cube depthcue dof \ - double drawf feedback fog fogindex font hello image light \ - lines list material mipmap model movelight nurbs pickdepth \ - picksquare plane planet polyoff polys quadric robot sccolorlight \ - scene scenebamb sceneflat select smooth stencil stroke surface \ - teaambient teapots tess tesswind texbind texgen texprox texsub \ - texturesurf torus trim unproject varray wrap +LIBS = -L$(TOP)/$(LIB_DIR) -l$(GLUT_LIB) -l$(GLEW_LIB) -l$(GLU_LIB) -l$(GL_LIB) $(APP_LIB_DEPS) + +PROGS = aaindex \ + aapoly \ + aargb \ + accanti \ + accpersp \ + alpha \ + alpha3D \ + anti \ + bezcurve \ + bezmesh \ + checker \ + clip \ + colormat \ + combiner \ + convolution \ + cube \ + cubemap \ + depthcue \ + dof \ + double \ + drawf \ + feedback \ + fog \ + fogcoord \ + fogindex \ + font \ + hello \ + histogram \ + image \ + light \ + lines \ + list \ + material \ + minmax \ + mipmap \ + model \ + movelight \ + multitex \ + multisamp \ + mvarray \ + nurbs \ + pickdepth \ + picksquare \ + plane \ + planet \ + pointp \ + polyoff \ + polys \ + quadric \ + robot \ + sccolorlight \ + scene \ + scenebamb \ + sceneflat \ + select \ + shadowmap \ + smooth \ + stencil \ + stroke \ + surface \ + surfpoints \ + teaambient \ + teapots \ + tess \ + tesswind \ + texbind \ + texgen \ + texprox \ + texsub \ + texturesurf \ + texture3d \ + torus \ + trim \ + unproject \ + varray \ + wrap diff --git a/progs/redbook/SConscript b/progs/redbook/SConscript index 24d7cff1b6..750ad36fe0 100644 --- a/progs/redbook/SConscript +++ b/progs/redbook/SConscript @@ -14,29 +14,39 @@ progs = [ 'checker', 'clip', 'colormat', + 'combiner', + 'convolution', 'cube', + 'cubemap', 'depthcue', 'dof', 'double', 'drawf', 'feedback', 'fog', + 'fogcoord', 'fogindex', 'font', 'hello', + 'histogram', 'image', 'light', 'lines', 'list', 'material', + 'minmax', 'mipmap', 'model', 'movelight', + 'multisamp', + 'multitex', + 'mvarray', 'nurbs', 'pickdepth', 'picksquare', 'plane', 'planet', + 'pointp', 'polyoff', 'polys', 'quadric', @@ -46,10 +56,12 @@ progs = [ 'scene', 'sceneflat', 'select', + 'shadowmap', 'smooth', 'stencil', 'stroke', 'surface', + 'surfpoints', 'teaambient', 'teapots', 'tess', @@ -59,6 +71,7 @@ progs = [ 'texprox', 'texsub', 'texturesurf', + 'texture3d', 'torus', 'trim', 'unproject', diff --git a/progs/redbook/combiner.c b/progs/redbook/combiner.c new file mode 100644 index 0000000000..92e4de484a --- /dev/null +++ b/progs/redbook/combiner.c @@ -0,0 +1,379 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* combiner.c + * This program renders a variety of quads showing different + * effects of texture combiner functions. + * + * The first row renders an untextured polygon (so you can + * compare the fragment colors) and then the 2 textures. + * The second row shows several different combiner functions + * on a single texture: replace, modulate, add, add-signed, + * and subtract. + * The third row shows the interpolate combiner function + * on a single texture with a constant color/alpha value, + * varying the amount of interpolation. + * The fourth row uses multitexturing with two textures + * and different combiner functions. + * The fifth row are some combiner experiments: using the + * scaling factor and reversing the order of subtraction + * for a combination function. + */ +#include <GL/glew.h> +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + +#define imageWidth 8 +#define imageHeight 8 +/* arrays for two textures */ +static GLubyte image0[imageHeight][imageWidth][4]; +static GLubyte image1[imageHeight][imageWidth][4]; + +static GLuint texName[4]; + +static void makeImages(void) +{ + int i, j, c; + for (i = 0; i < imageHeight; i++) { + for (j = 0; j < imageWidth; j++) { + c = ((i&2)==0)*255; /* horiz b & w stripes */ + image0[i][j][0] = (GLubyte) c; + image0[i][j][1] = (GLubyte) c; + image0[i][j][2] = (GLubyte) c; + image0[i][j][3] = (GLubyte) 255; + c = ((j&4)!=0)*128; /* wider vertical 50% cyan and black stripes */ + image1[i][j][0] = (GLubyte) 0; + image1[i][j][1] = (GLubyte) c; + image1[i][j][2] = (GLubyte) c; + image1[i][j][3] = (GLubyte) 255; + } + } +} + +static void init(void) +{ + glClearColor (0.0, 0.0, 0.0, 0.0); + glShadeModel(GL_SMOOTH); + + makeImages(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glGenTextures(4, texName); + + glBindTexture(GL_TEXTURE_2D, texName[0]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, + 0, GL_RGBA, GL_UNSIGNED_BYTE, image0); + + glBindTexture(GL_TEXTURE_2D, texName[1]); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, imageWidth, imageHeight, + 0, GL_RGBA, GL_UNSIGNED_BYTE, image1); + +/* smooth-shaded polygon with multiple texture coordinates */ + glNewList (1, GL_COMPILE); + glBegin(GL_QUADS); + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 0.0); + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 0.0); + glColor3f (0.5, 1.0, 0.25); + glVertex3f(0.0, 0.0, 0.0); + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 0.0, 2.0); + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 0.0, 2.0); + glColor3f (1.0, 1.0, 1.0); + glVertex3f(0.0, 1.0, 0.0); + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 2.0, 2.0); + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 2.0, 2.0); + glColor3f (1.0, 1.0, 1.0); + glVertex3f(1.0, 1.0, 0.0); + glMultiTexCoord2fARB(GL_TEXTURE0_ARB, 2.0, 0.0); + glMultiTexCoord2fARB(GL_TEXTURE1_ARB, 2.0, 0.0); + glColor3f (1.0, 0.5, 0.25); + glVertex3f(1.0, 0.0, 0.0); + glEnd(); + glEndList (); +} + +static void display(void) +{ + static GLfloat constColor[4] = {0.0, 0.0, 0.0, 0.0}; /* for use as constant texture color */ + + glClear(GL_COLOR_BUFFER_BIT); + + glDisable(GL_TEXTURE_2D); /* untextured polygon--see the "fragment" colors */ + glPushMatrix(); + glTranslatef(0.0, 5.0, 0.0); + glCallList(1); + glPopMatrix(); + + glEnable(GL_TEXTURE_2D); +/* draw ordinary textured polys; 1 texture unit; combine mode disabled */ + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + glPushMatrix(); + glBindTexture(GL_TEXTURE_2D, texName[0]); + glTranslatef(1.0, 5.0, 0.0); + glCallList(1); + glPopMatrix(); + + glPushMatrix(); + glBindTexture(GL_TEXTURE_2D, texName[1]); + glTranslatef(2.0, 5.0, 0.0); + glCallList(1); + glPopMatrix(); + +/* different combine modes enabled; 1 texture unit + * defaults are: + * glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + * glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + * glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + * glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + */ + glBindTexture(GL_TEXTURE_2D, texName[0]); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + glPushMatrix(); + glTranslatef(1.0, 4.0, 0.0); + glCallList(1); + glPopMatrix(); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + glPushMatrix(); + glTranslatef(2.0, 4.0, 0.0); + glCallList(1); + glPopMatrix(); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD); + glPushMatrix(); + glTranslatef(3.0, 4.0, 0.0); + glCallList(1); + glPopMatrix(); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB); + glPushMatrix(); + glTranslatef(4.0, 4.0, 0.0); + glCallList(1); + glPopMatrix(); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB); + glPushMatrix(); + glTranslatef(5.0, 4.0, 0.0); + glCallList(1); + glPopMatrix(); + +/* interpolate combine with constant color; 1 texture unit + * use different alpha values for constant color + * defaults are: + * glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + * glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + * glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + * glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + * glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB); + * glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA); + */ + constColor[3] = 0.2; + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor); + glBindTexture(GL_TEXTURE_2D, texName[0]); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_INTERPOLATE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE2_RGB_ARB, GL_CONSTANT_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND2_RGB_ARB, GL_SRC_ALPHA); + glPushMatrix(); + glTranslatef(1.0, 3.0, 0.0); + glCallList(1); + glPopMatrix(); + + constColor[3] = 0.4; + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor); + glPushMatrix(); + glTranslatef(2.0, 3.0, 0.0); + glCallList(1); + glPopMatrix(); + + constColor[3] = 0.6; + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor); + glPushMatrix(); + glTranslatef(3.0, 3.0, 0.0); + glCallList(1); + glPopMatrix(); + + constColor[4] = 0.8; + glTexEnvfv(GL_TEXTURE_ENV, GL_TEXTURE_ENV_COLOR, constColor); + glPushMatrix(); + glTranslatef(4.0, 3.0, 0.0); + glCallList(1); + glPopMatrix(); + +/* combine textures 0 & 1 + * defaults are: + * glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_TEXTURE); + * glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + * glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_PREVIOUS_ARB); + * glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + */ + + glActiveTextureARB (GL_TEXTURE0_ARB); + glEnable (GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texName[0]); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glActiveTextureARB (GL_TEXTURE1_ARB); + glEnable (GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texName[1]); + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); + glPushMatrix(); + glTranslatef(1.0, 2.0, 0.0); + glCallList(1); + glPopMatrix(); + + /* try different combiner modes of texture unit 1 */ + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glPushMatrix(); + glTranslatef(2.0, 2.0, 0.0); + glCallList(1); + glPopMatrix(); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD); + glPushMatrix(); + glTranslatef(3.0, 2.0, 0.0); + glCallList(1); + glPopMatrix(); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_ADD_SIGNED_ARB); + glPushMatrix(); + glTranslatef(4.0, 2.0, 0.0); + glCallList(1); + glPopMatrix(); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB); + glPushMatrix(); + glTranslatef(5.0, 2.0, 0.0); + glCallList(1); + glPopMatrix(); + +/* some experiments */ + +/* see the effect of RGB_SCALE */ + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 2.0); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_REPLACE); + glPushMatrix(); + glTranslatef(1.0, 1.0, 0.0); + glCallList(1); + glPopMatrix(); + + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_MODULATE); + glPushMatrix(); + glTranslatef(2.0, 1.0, 0.0); + glCallList(1); + glPopMatrix(); + glTexEnvf(GL_TEXTURE_ENV, GL_RGB_SCALE_ARB, 1.0); + +/* using SOURCE0 and SOURCE1, reverse the order of subtraction Arg1-Arg0 */ + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_COMBINE_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_COMBINE_RGB_ARB, GL_SUBTRACT_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE0_RGB_ARB, GL_PREVIOUS_ARB); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND0_RGB_ARB, GL_SRC_COLOR); + glTexEnvf(GL_TEXTURE_ENV, GL_SOURCE1_RGB_ARB, GL_TEXTURE); + glTexEnvf(GL_TEXTURE_ENV, GL_OPERAND1_RGB_ARB, GL_SRC_COLOR); + glPushMatrix(); + glTranslatef(5.0, 1.0, 0.0); + glCallList(1); + glPopMatrix(); + + glActiveTextureARB (GL_TEXTURE1_ARB); /* deactivate multitexturing */ + glDisable (GL_TEXTURE_2D); + glActiveTextureARB (GL_TEXTURE0_ARB); /* activate single texture unit */ + + glFlush(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluOrtho2D(0.0, 7.0, 0.0, 7.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +static void keyboard (unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + break; + default: + break; + } +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); + glutInitWindowSize(400, 400); + glutInitWindowPosition(100, 100); + glutCreateWindow(argv[0]); + glewInit(); + init(); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/convolution.c b/progs/redbook/convolution.c new file mode 100644 index 0000000000..0898ef25e1 --- /dev/null +++ b/progs/redbook/convolution.c @@ -0,0 +1,214 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * convolution.c + * Use various 2D convolutions filters to find edges in an image. + * + */ +#include <GL/glew.h> +#include <GL/glut.h> +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> + + +static GLuint bswap(GLuint x) +{ + const GLuint ui = 1; + const GLubyte *ubp = (const GLubyte *) &ui; + if (*ubp == 1) { + /* we're on little endiang so byteswap x */ + GLsizei y = ((x >> 24) + | ((x >> 8) & 0xff00) + | ((x << 8) & 0xff0000) + | ((x << 24) & 0xff000000)); + return y; + } + else { + return x; + } +} + + +static GLubyte * +readImage( const char* filename, GLsizei* width, GLsizei *height ) +{ + int n; + GLubyte* pixels; + + FILE* infile = fopen( filename, "rb" ); + + if ( !infile ) { + fprintf( stderr, "Unable to open file '%s'\n", filename ); + exit(1); + } + + fread( width, sizeof( GLsizei ), 1, infile ); + fread( height, sizeof( GLsizei ), 1, infile ); + + *width = bswap(*width); + *height = bswap(*height); + + assert(*width > 0); + assert(*height > 0); + + n = 3 * (*width) * (*height); + + pixels = (GLubyte *) malloc( n * sizeof( GLubyte )); + if ( !pixels ) { + fprintf( stderr, "Unable to malloc() bytes for pixels\n" ); + fclose( infile ); + return NULL; + } + + fread( pixels, sizeof( GLubyte ), n, infile ); + + fclose( infile ); + + return pixels; +} + + +GLubyte *pixels; +GLsizei width, height; + +GLfloat horizontal[3][3] = { + { 0, -1, 0 }, + { 0, 1, 0 }, + { 0, 0, 0 } +}; + +GLfloat vertical[3][3] = { + { 0, 0, 0 }, + { -1, 1, 0 }, + { 0, 0, 0 } +}; + +GLfloat laplacian[3][3] = { + { -0.125, -0.125, -0.125 }, + { -0.125, 1.0 , -0.125 }, + { -0.125, -0.125, -0.125 }, +}; + + +static void init(void) +{ + if (!glutExtensionSupported("GL_ARB_imaging")) { + fprintf(stderr, "Sorry, this program requires GL_ARB_imaging.\n"); + exit(1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glClearColor(0.0, 0.0, 0.0, 0.0); + + printf("Using the horizontal filter\n"); + glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, + 3, 3, GL_LUMINANCE, GL_FLOAT, horizontal); + glEnable(GL_CONVOLUTION_2D); +} + +static void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + glRasterPos2i( 1, 1); + glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + glFlush(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, w, 0, h, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 'h' : + printf("Using a horizontal filter\n"); + glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3, + GL_LUMINANCE, GL_FLOAT, horizontal); + break; + + case 'v' : + printf("Using the vertical filter\n"); + glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3, + GL_LUMINANCE, GL_FLOAT, vertical); + break; + + case 'l' : + printf("Using the laplacian filter\n"); + glConvolutionFilter2D(GL_CONVOLUTION_2D, GL_LUMINANCE, 3, 3, + GL_LUMINANCE, GL_FLOAT, laplacian); + break; + + case 27: + exit(0); + } + glutPostRedisplay(); +} + +/* Main Loop + * Open window with initial window size, title bar, + * RGBA display mode, and handle input events. + */ +int main(int argc, char** argv) +{ + pixels = readImage("leeds.bin", &width, &height); + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGBA); + glutInitWindowSize(width, height); + glutInitWindowPosition(100, 100); + glutCreateWindow(argv[0]); + glewInit(); + init(); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutDisplayFunc(display); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/cubemap.c b/progs/redbook/cubemap.c new file mode 100644 index 0000000000..92026c7089 --- /dev/null +++ b/progs/redbook/cubemap.c @@ -0,0 +1,205 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* cubemap.c + * + * This program demonstrates cube map textures. + * Six different colored checker board textures are + * created and applied to a lit sphere. + * + * Pressing the 'f' and 'b' keys translate the viewer + * forward and backward. + */ + +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + +#define imageSize 4 +static GLubyte image1[imageSize][imageSize][4]; +static GLubyte image2[imageSize][imageSize][4]; +static GLubyte image3[imageSize][imageSize][4]; +static GLubyte image4[imageSize][imageSize][4]; +static GLubyte image5[imageSize][imageSize][4]; +static GLubyte image6[imageSize][imageSize][4]; + +static GLdouble ztrans = 0.0; + +static void makeImages(void) +{ + int i, j, c; + + for (i = 0; i < imageSize; i++) { + for (j = 0; j < imageSize; j++) { + c = ( ((i & 0x1) == 0) ^ ((j & 0x1) == 0) ) * 255; + image1[i][j][0] = (GLubyte) c; + image1[i][j][1] = (GLubyte) c; + image1[i][j][2] = (GLubyte) c; + image1[i][j][3] = (GLubyte) 255; + + image2[i][j][0] = (GLubyte) c; + image2[i][j][1] = (GLubyte) c; + image2[i][j][2] = (GLubyte) 0; + image2[i][j][3] = (GLubyte) 255; + + image3[i][j][0] = (GLubyte) c; + image3[i][j][1] = (GLubyte) 0; + image3[i][j][2] = (GLubyte) c; + image3[i][j][3] = (GLubyte) 255; + + image4[i][j][0] = (GLubyte) 0; + image4[i][j][1] = (GLubyte) c; + image4[i][j][2] = (GLubyte) c; + image4[i][j][3] = (GLubyte) 255; + + image5[i][j][0] = (GLubyte) 255; + image5[i][j][1] = (GLubyte) c; + image5[i][j][2] = (GLubyte) c; + image5[i][j][3] = (GLubyte) 255; + + image6[i][j][0] = (GLubyte) c; + image6[i][j][1] = (GLubyte) c; + image6[i][j][2] = (GLubyte) 255; + image6[i][j][3] = (GLubyte) 255; + } + } +} + +static void init(void) +{ + GLfloat diffuse[4] = {1.0, 1.0, 1.0, 1.0}; + + glClearColor (0.0, 0.0, 0.0, 0.0); + glEnable(GL_DEPTH_TEST); + glShadeModel(GL_SMOOTH); + + makeImages(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_T, GL_REPEAT); + glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_WRAP_R, GL_REPEAT); + glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MAG_FILTER, GL_NEAREST); + glTexParameteri(GL_TEXTURE_CUBE_MAP_EXT, GL_TEXTURE_MIN_FILTER, GL_NEAREST); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X_EXT, 0, GL_RGBA, imageSize, + imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image1); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_X_EXT, 0, GL_RGBA, imageSize, + imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image4); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Y_EXT, 0, GL_RGBA, imageSize, + imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image2); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Y_EXT, 0, GL_RGBA, imageSize, + imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image5); + glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_Z_EXT, 0, GL_RGBA, imageSize, + imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image3); + glTexImage2D(GL_TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT, 0, GL_RGBA, imageSize, + imageSize, 0, GL_RGBA, GL_UNSIGNED_BYTE, image6); + glTexGeni(GL_S, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); + glTexGeni(GL_T, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); + glTexGeni(GL_R, GL_TEXTURE_GEN_MODE, GL_NORMAL_MAP_EXT); + glEnable(GL_TEXTURE_GEN_S); + glEnable(GL_TEXTURE_GEN_T); + glEnable(GL_TEXTURE_GEN_R); + + glTexEnvf(GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); + + glEnable(GL_TEXTURE_CUBE_MAP_EXT); + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + glMaterialfv (GL_FRONT, GL_DIFFUSE, diffuse); +} + +static void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix (); + glTranslatef (0.0, 0.0, ztrans); + glutSolidSphere (5.0, 20, 10); + glPopMatrix (); + glutSwapBuffers(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(40.0, (GLfloat) w/(GLfloat) h, 1.0, 300.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -20.0); +} + +static void keyboard (unsigned char key, int x, int y) +{ + switch (key) { + case 'f': + ztrans = ztrans - 0.2; + glutPostRedisplay(); + break; + case 'b': + ztrans = ztrans + 0.2; + glutPostRedisplay(); + break; + case 27: + exit(0); + break; + default: + break; + } +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize(400, 400); + glutInitWindowPosition(100, 100); + glutCreateWindow (argv[0]); + init (); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/fogcoord.c b/progs/redbook/fogcoord.c new file mode 100644 index 0000000000..17ef7ae5f3 --- /dev/null +++ b/progs/redbook/fogcoord.c @@ -0,0 +1,194 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * fogcoord.c + * + * This program demonstrates the use of explicit fog + * coordinates. You can press the keyboard and change + * the fog coordinate value at any vertex. You can + * also switch between using explicit fog coordinates + * and the default fog generation mode. + * + * Pressing the 'f' and 'b' keys move the viewer forward + * and backwards. + * Pressing 'c' initiates the default fog generation. + * Pressing capital 'C' restores explicit fog coordinates. + * Pressing '1', '2', '3', '8', '9', and '0' add or + * subtract from the fog coordinate values at one of the + * three vertices of the triangle. + */ + +#include <GL/glew.h> +#include <GL/glut.h> +#include <math.h> +#include <stdlib.h> +#include <stdio.h> + +static GLfloat f1, f2, f3; + +/* Initialize fog + */ +static void init(void) +{ + GLfloat fogColor[4] = {0.0, 0.25, 0.25, 1.0}; + f1 = 1.0f; + f2 = 5.0f; + f3 = 10.0f; + + glEnable(GL_FOG); + glFogi (GL_FOG_MODE, GL_EXP); + glFogfv (GL_FOG_COLOR, fogColor); + glFogf (GL_FOG_DENSITY, 0.25); + glHint (GL_FOG_HINT, GL_DONT_CARE); + glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); + glClearColor(0.0, 0.25, 0.25, 1.0); /* fog color */ +} + +/* display() draws a triangle at an angle. + */ +static void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + glColor3f (1.0f, 0.75f, 0.0f); + glBegin (GL_TRIANGLES); + glFogCoordfEXT (f1); + glVertex3f (2.0f, -2.0f, 0.0f); + glFogCoordfEXT (f2); + glVertex3f (-2.0f, 0.0f, -5.0f); + glFogCoordfEXT (f3); + glVertex3f (0.0f, 2.0f, -10.0f); + glEnd(); + + glutSwapBuffers(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective (45.0, 1.0, 0.25, 25.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity (); + glTranslatef (0.0, 0.0, -5.0); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 'c': + glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FRAGMENT_DEPTH_EXT); + glutPostRedisplay(); + break; + case 'C': + glFogi(GL_FOG_COORDINATE_SOURCE_EXT, GL_FOG_COORDINATE_EXT); + glutPostRedisplay(); + break; + case '1': + f1 = f1 + 0.25; + glutPostRedisplay(); + break; + case '2': + f2 = f2 + 0.25; + glutPostRedisplay(); + break; + case '3': + f3 = f3 + 0.25; + glutPostRedisplay(); + break; + case '8': + if (f1 > 0.25) { + f1 = f1 - 0.25; + glutPostRedisplay(); + } + break; + case '9': + if (f2 > 0.25) { + f2 = f2 - 0.25; + glutPostRedisplay(); + } + break; + case '0': + if (f3 > 0.25) { + f3 = f3 - 0.25; + glutPostRedisplay(); + } + break; + case 'b': + glMatrixMode (GL_MODELVIEW); + glTranslatef (0.0, 0.0, -0.25); + glutPostRedisplay(); + break; + case 'f': + glMatrixMode (GL_MODELVIEW); + glTranslatef (0.0, 0.0, 0.25); + glutPostRedisplay(); + break; + case 27: + exit(0); + break; + default: + break; + } +} + + +/* Main Loop + * Open window with initial window size, title bar, + * RGBA display mode, depth buffer, and handle input events. + */ +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB); + glutInitWindowSize(500, 500); + glutCreateWindow(argv[0]); + glewInit(); + init(); + glutReshapeFunc (reshape); + glutKeyboardFunc (keyboard); + glutDisplayFunc (display); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/histogram.c b/progs/redbook/histogram.c new file mode 100644 index 0000000000..70a5282577 --- /dev/null +++ b/progs/redbook/histogram.c @@ -0,0 +1,209 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * histogram.c + * Compute the histogram of the image. This program illustrates the + * use of the glHistogram() function. + */ + +#include <GL/glew.h> +#include <GL/glut.h> +#include <assert.h> +#include <stdlib.h> +#include <stdio.h> + +#define HISTOGRAM_SIZE 256 /* Must be a power of 2 */ + + +static GLubyte *pixels; +static GLsizei width, height; + + + +static GLuint bswap(GLuint x) +{ + const GLuint ui = 1; + const GLubyte *ubp = (const GLubyte *) &ui; + if (*ubp == 1) { + /* we're on little endiang so byteswap x */ + GLsizei y = ((x >> 24) + | ((x >> 8) & 0xff00) + | ((x << 8) & 0xff0000) + | ((x << 24) & 0xff000000)); + return y; + } + else { + return x; + } +} + + +static GLubyte* +readImage( const char* filename, GLsizei* width, GLsizei *height ) +{ + int n; + GLubyte* pixels; + + FILE* infile = fopen( filename, "rb" ); + + if ( !infile ) { + fprintf( stderr, "Unable to open file '%s'\n", filename ); + exit(1); + } + + fread( width, sizeof( GLsizei ), 1, infile ); + fread( height, sizeof( GLsizei ), 1, infile ); + + *width = bswap(*width); + *height = bswap(*height); + + n = 3 * (*width) * (*height); + + pixels = (GLubyte *) malloc( n * sizeof( GLubyte )); + if ( !pixels ) { + fprintf( stderr, "Unable to malloc() bytes for pixels\n" ); + fclose( infile ); + return NULL; + } + + fread( pixels, sizeof( GLubyte ), n, infile ); + + fclose( infile ); + + return pixels; +} + +static void init(void) +{ + if (!glutExtensionSupported("GL_ARB_imaging")) { + fprintf(stderr, "Sorry, this program requires GL_ARB_imaging.\n"); + exit(1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glClearColor(0.0, 0.0, 0.0, 0.0); + + glHistogram(GL_HISTOGRAM, HISTOGRAM_SIZE, GL_RGB, GL_FALSE); + glEnable(GL_HISTOGRAM); +} + +static void display(void) +{ + int i; + GLushort values[HISTOGRAM_SIZE][3]; + + glClear(GL_COLOR_BUFFER_BIT); + glRasterPos2i(1, 1); + glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + + glGetHistogram(GL_HISTOGRAM, GL_TRUE, GL_RGB, GL_UNSIGNED_SHORT, values); + + /* Plot histogram */ + + glBegin(GL_LINE_STRIP); + glColor3f(1.0, 0.0, 0.0); + for ( i = 0; i < HISTOGRAM_SIZE; i++ ) + glVertex2s(i, values[i][0]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glColor3f(0.0, 1.0, 0.0); + for ( i = 0; i < HISTOGRAM_SIZE; i++ ) + glVertex2s(i, values[i][1]); + glEnd(); + + glBegin(GL_LINE_STRIP); + glColor3f(0.0, 0.0, 1.0); + for ( i = 0; i < HISTOGRAM_SIZE; i++ ) + glVertex2s(i, values[i][2]); + glEnd(); + glFlush(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, 256, 0, 10000, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); +} + +static void keyboard(unsigned char key, int x, int y) +{ + static GLboolean sink = GL_FALSE; + + switch (key) { + case 's' : + sink = !sink; + glHistogram(GL_HISTOGRAM, HISTOGRAM_SIZE, GL_RGB, sink); + break; + + case 27: + exit(0); + } + glutPostRedisplay(); + +} + +/* Main Loop + * Open window with initial window size, title bar, + * RGBA display mode, and handle input events. + */ +int main(int argc, char** argv) +{ + pixels = readImage("leeds.bin", &width, &height); + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); + glutInitWindowSize(width, height); + glutInitWindowPosition(100, 100); + glutCreateWindow(argv[0]); + glewInit(); + init(); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutDisplayFunc(display); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/leeds.bin b/progs/redbook/leeds.bin Binary files differnew file mode 100644 index 0000000000..5dc105e676 --- /dev/null +++ b/progs/redbook/leeds.bin diff --git a/progs/redbook/minmax.c b/progs/redbook/minmax.c new file mode 100644 index 0000000000..8281800ba4 --- /dev/null +++ b/progs/redbook/minmax.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * minmax.c + * Determine the minimum and maximum values of a group of pixels. + * This demonstrates use of the glMinmax() call. + */ +#include <GL/glew.h> +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + + +static GLubyte *pixels; +static GLsizei width, height; + + +static GLuint bswap(GLuint x) +{ + const GLuint ui = 1; + const GLubyte *ubp = (const GLubyte *) &ui; + if (*ubp == 1) { + /* we're on little endiang so byteswap x */ + GLsizei y = ((x >> 24) + | ((x >> 8) & 0xff00) + | ((x << 8) & 0xff0000) + | ((x << 24) & 0xff000000)); + return y; + } + else { + return x; + } +} + + +static GLubyte * +readImage( const char* filename, GLsizei* width, GLsizei *height ) +{ + int n; + GLubyte* pixels; + + FILE* infile = fopen( filename, "rb" ); + + if ( !infile ) { + fprintf( stderr, "Unable to open file '%s'\n", filename ); + return NULL; + } + + fread( width, sizeof( GLsizei ), 1, infile ); + fread( height, sizeof( GLsizei ), 1, infile ); + + *width = bswap(*width); + *height = bswap(*height); + + n = 3 * (*width) * (*height); + + pixels = (GLubyte *) malloc( n * sizeof( GLubyte )); + if ( !pixels ) { + fprintf( stderr, "Unable to malloc() bytes for pixels\n" ); + fclose( infile ); + return NULL; + } + + fread( pixels, sizeof( GLubyte ), n, infile ); + + fclose( infile ); + + return pixels; +} + +static void init(void) +{ + if (!glutExtensionSupported("GL_ARB_imaging")) { + fprintf(stderr, "Sorry, this program requires GL_ARB_imaging.\n"); + exit(1); + } + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glClearColor(0.0, 0.0, 0.0, 0.0); + + glMinmax(GL_MINMAX, GL_RGB, GL_FALSE); + glEnable(GL_MINMAX); +} + +static void display(void) +{ + GLubyte values[6]; + + glClear(GL_COLOR_BUFFER_BIT); + glRasterPos2i(1, 1); + glDrawPixels(width, height, GL_RGB, GL_UNSIGNED_BYTE, pixels); + glFlush(); + + glGetMinmax(GL_MINMAX, GL_TRUE, GL_RGB, GL_UNSIGNED_BYTE, values); + printf(" Red : min = %d max = %d\n", values[0], values[3]); + printf(" Green : min = %d max = %d\n", values[1], values[4]); + printf(" Blue : min = %d max = %d\n", values[2], values[5]); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + glOrtho(0, w, 0, h, -1.0, 1.0); + glMatrixMode(GL_MODELVIEW); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + } +} + +/* Main Loop + * Open window with initial window size, title bar, + * RGBA display mode, and handle input events. + */ +int main(int argc, char** argv) +{ + pixels = readImage("leeds.bin", &width, &height); + + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB); + glutInitWindowSize(width, height); + glutInitWindowPosition(100, 100); + glutCreateWindow(argv[0]); + glewInit(); + init(); + glutReshapeFunc(reshape); + glutKeyboardFunc(keyboard); + glutDisplayFunc(display); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/multisamp.c b/progs/redbook/multisamp.c new file mode 100644 index 0000000000..38bd572fc1 --- /dev/null +++ b/progs/redbook/multisamp.c @@ -0,0 +1,188 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * multisamp.c + * This program draws shows how to use multisampling to + * draw anti-aliased geometric primitives. The same + * display list, a pinwheel of triangles and lines of + * varying widths, is rendered twice. Multisampling is + * enabled when the left side is drawn. Multisampling is + * disabled when the right side is drawn. + * + * Pressing the 'b' key toggles drawing of the checkerboard + * background. Antialiasing is sometimes easier to see + * when objects are rendered over a contrasting background. + */ +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + +static int bgtoggle = 1; + +/* + * Print out state values related to multisampling. + * Create display list with "pinwheel" of lines and + * triangles. + */ +static void init(void) +{ + static GLint buf[1], sbuf[1]; + int i, j; + + glClearColor(0.0, 0.0, 0.0, 0.0); + glGetIntegerv (GL_SAMPLE_BUFFERS_ARB, buf); + printf ("number of sample buffers is %d\n", buf[0]); + glGetIntegerv (GL_SAMPLES_ARB, sbuf); + printf ("number of samples is %d\n", sbuf[0]); + + glNewList (1, GL_COMPILE); + for (i = 0; i < 19; i++) { + glPushMatrix(); + glRotatef(360.0*(float)i/19.0, 0.0, 0.0, 1.0); + glColor3f (1.0, 1.0, 1.0); + glLineWidth((i%3)+1.0); + glBegin (GL_LINES); + glVertex2f (0.25, 0.05); + glVertex2f (0.9, 0.2); + glEnd (); + glColor3f (0.0, 1.0, 1.0); + glBegin (GL_TRIANGLES); + glVertex2f (0.25, 0.0); + glVertex2f (0.9, 0.0); + glVertex2f (0.875, 0.10); + glEnd (); + glPopMatrix(); + } + glEndList (); + + glNewList (2, GL_COMPILE); + glColor3f (1.0, 0.5, 0.0); + glBegin (GL_QUADS); + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + if (((i + j) % 2) == 0) { + glVertex2f (-2.0 + (i * 0.25), -2.0 + (j * 0.25)); + glVertex2f (-2.0 + (i * 0.25), -1.75 + (j * 0.25)); + glVertex2f (-1.75 + (i * 0.25), -1.75 + (j * 0.25)); + glVertex2f (-1.75 + (i * 0.25), -2.0 + (j * 0.25)); + } + } + } + glEnd (); + glEndList (); +} + +/* Draw two sets of primitives, so that you can + * compare the user of multisampling against its absence. + * + * This code enables antialiasing and draws one display list + * and disables and draws the other display list + */ +static void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT); + + if (bgtoggle) + glCallList (2); + + glEnable (GL_MULTISAMPLE_ARB); + glPushMatrix(); + glTranslatef (-1.0, 0.0, 0.0); + glCallList (1); + glPopMatrix(); + + glDisable (GL_MULTISAMPLE_ARB); + glPushMatrix(); + glTranslatef (1.0, 0.0, 0.0); + glCallList (1); + glPopMatrix(); + glutSwapBuffers(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, w, h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + if (w <= (2 * h)) + gluOrtho2D (-2.0, 2.0, + -2.0*(GLfloat)h/(GLfloat)w, 2.0*(GLfloat)h/(GLfloat)w); + else + gluOrtho2D (-2.0*(GLfloat)w/(GLfloat)h, + 2.0*(GLfloat)w/(GLfloat)h, -2.0, 2.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 'b': + case 'B': + bgtoggle = !bgtoggle; + glutPostRedisplay(); + break; + case 27: /* Escape Key */ + exit(0); + default: + break; + } +} + +/* Main Loop + * Open window with initial window size, title bar, + * RGBA display mode, and handle input events. + */ +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_DOUBLE | GLUT_RGB | GLUT_MULTISAMPLE); + glutInitWindowSize (600, 300); + glutCreateWindow (argv[0]); + init(); + glutReshapeFunc (reshape); + glutKeyboardFunc (keyboard); + glutDisplayFunc (display); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/multitex.c b/progs/redbook/multitex.c new file mode 100644 index 0000000000..118f0ea77e --- /dev/null +++ b/progs/redbook/multitex.c @@ -0,0 +1,177 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* multitex.c + */ +#include <GL/glew.h> +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + + +static GLubyte texels0[32][32][4]; +static GLubyte texels1[16][16][4]; + +static void makeCheckImages(void) +{ + int i, j; + + for (i = 0; i < 32; i++) { + for (j = 0; j < 32; j++) { + texels0[i][j][0] = (GLubyte) (255 * i / 31); + texels0[i][j][1] = (GLubyte) (255 * j / 31); + texels0[i][j][2] = (GLubyte) (i*j)/255; + texels0[i][j][3] = (GLubyte) 255; + } + } + + for (i = 0; i < 16; i++) { + for (j = 0; j < 16; j++) { + texels1[i][j][0] = (GLubyte) 255; + texels1[i][j][1] = (GLubyte) (255 * i / 15); + texels1[i][j][2] = (GLubyte) (255 * j / 15); + texels1[i][j][3] = (GLubyte) 255; + } + } +} + +static void init(void) +{ + GLuint texNames[2]; + + glClearColor (0.0, 0.0, 0.0, 0.0); + glShadeModel(GL_FLAT); + glEnable(GL_DEPTH_TEST); + + makeCheckImages(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glGenTextures(2, texNames); + glBindTexture(GL_TEXTURE_2D, texNames[0]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 32, 32, 0, GL_RGBA, + GL_UNSIGNED_BYTE, texels0); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_REPEAT); + + glBindTexture(GL_TEXTURE_2D, texNames[1]); + glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, 16, 16, 0, GL_RGBA, + GL_UNSIGNED_BYTE, texels1); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + /* Use the two texture objects to define two texture units + * for use in multitexturing */ + glActiveTextureARB (GL_TEXTURE0_ARB); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texNames[0]); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_REPLACE); + glMatrixMode (GL_TEXTURE); + glLoadIdentity(); + glTranslatef(0.5f, 0.5f, 0.0f); + glRotatef(45.0f, 0.0f, 0.0f, 1.0f); + glTranslatef(-0.5f, -0.5f, 0.0f); + glMatrixMode (GL_MODELVIEW); + glActiveTextureARB (GL_TEXTURE1_ARB); + glEnable(GL_TEXTURE_2D); + glBindTexture(GL_TEXTURE_2D, texNames[1]); + glTexEnvi (GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE); +} + +static void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBegin(GL_TRIANGLES); + glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.0, 0.0); + glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 1.0, 0.0); + glVertex2f(0.0, 0.0); + glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 0.5, 1.0); + glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 0.5, 0.0); + glVertex2f(50.0, 100.0); + glMultiTexCoord2fARB (GL_TEXTURE0_ARB, 1.0, 0.0); + glMultiTexCoord2fARB (GL_TEXTURE1_ARB, 1.0, 1.0); + glVertex2f(100.0, 0.0); + glEnd(); + glFlush(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + if (w <= h) + gluOrtho2D(0.0, 100.0, 0.0, 100.0 * (GLdouble)h/(GLdouble)w); + else + gluOrtho2D(0.0, 100.0 * (GLdouble)w/(GLdouble)h, 0.0, 100.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + break; + } +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize(250, 250); + glutInitWindowPosition(100, 100); + glutCreateWindow(argv[0]); + glewInit(); + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutKeyboardFunc (keyboard); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/mvarray.c b/progs/redbook/mvarray.c new file mode 100644 index 0000000000..1022723ad9 --- /dev/null +++ b/progs/redbook/mvarray.c @@ -0,0 +1,136 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * mvarray.c + * This program demonstrates multiple vertex arrays, + * specifically the OpenGL routine glMultiDrawElements(). + */ + +#include <GL/glew.h> +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + +#ifdef GL_VERSION_1_3 + +static void setupPointer(void) +{ + static GLint vertices[] = {25, 25, + 75, 75, + 100, 125, + 150, 75, + 200, 175, + 250, 150, + 300, 125, + 100, 200, + 150, 250, + 200, 225, + 250, 300, + 300, 250}; + + glEnableClientState (GL_VERTEX_ARRAY); + glVertexPointer (2, GL_INT, 0, vertices); +} + +static void init(void) +{ + glClearColor (0.0, 0.0, 0.0, 0.0); + glShadeModel (GL_SMOOTH); + setupPointer (); +} + +static void display(void) +{ + static GLubyte oneIndices[] = {0, 1, 2, 3, 4, 5, 6}; + static GLubyte twoIndices[] = {1, 7, 8, 9, 10, 11}; + static GLsizei count[] = {7, 6}; + static GLvoid * indices[2] = {oneIndices, twoIndices}; + + glClear (GL_COLOR_BUFFER_BIT); + glColor3f (1.0, 1.0, 1.0); + glMultiDrawElementsEXT (GL_LINE_STRIP, count, GL_UNSIGNED_BYTE, + (const GLvoid **) indices, 2); + glFlush (); +} + +static void reshape (int w, int h) +{ + glViewport (0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + gluOrtho2D (0.0, (GLdouble) w, 0.0, (GLdouble) h); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + break; + } +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_SINGLE | GLUT_RGB); + glutInitWindowSize (350, 350); + glutInitWindowPosition (100, 100); + glutCreateWindow (argv[0]); + glewInit(); + init (); + glutDisplayFunc(display); + glutReshapeFunc(reshape); + glutKeyboardFunc (keyboard); + glutMainLoop(); + return 0; +} +#else +int main(int argc, char** argv) +{ + fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0.\n"); + fprintf (stderr, "If your implementation of OpenGL Version 1.0 has the right extensions,\n"); + fprintf (stderr, "you may be able to modify this program to make it run.\n"); + return 0; +} +#endif diff --git a/progs/redbook/pointp.c b/progs/redbook/pointp.c new file mode 100644 index 0000000000..b273623d85 --- /dev/null +++ b/progs/redbook/pointp.c @@ -0,0 +1,179 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * pointp.c + * This program demonstrates point parameters and their effect + * on point primitives. + * 250 points are randomly generated within a 10 by 10 by 40 + * region, centered at the origin. In some modes (including the + * default), points that are closer to the viewer will appear larger. + * + * Pressing the 'l', 'q', and 'c' keys switch the point + * parameters attenuation mode to linear, quadratic, or constant, + * respectively. + * Pressing the 'f' and 'b' keys move the viewer forward + * and backwards. In either linear or quadratic attenuation + * mode, the distance from the viewer to the point will change + * the size of the point primitive. + * Pressing the '+' and '-' keys will change the current point + * size. In this program, the point size is bounded, so it + * will not get less than 2.0, nor greater than GL_POINT_SIZE_MAX. + */ + +#include <GL/glew.h> +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + +static GLfloat psize = 7.0; +static GLfloat pmax[1]; +static GLfloat constant[3] = {1.0, 0.0, 0.0}; +static GLfloat linear[3] = {0.0, 0.12, 0.0}; +static GLfloat quadratic[3] = {0.0, 0.0, 0.01}; + +static void init(void) +{ + int i; + + srand (12345); + + glNewList(1, GL_COMPILE); + glBegin (GL_POINTS); + for (i = 0; i < 250; i++) { + glColor3f (1.0, ((rand()/(float) RAND_MAX) * 0.5) + 0.5, + rand()/(float) RAND_MAX); +/* randomly generated vertices: + -5 < x < 5; -5 < y < 5; -5 < z < -45 */ + glVertex3f ( ((rand()/(float)RAND_MAX) * 10.0) - 5.0, + ((rand()/(float)RAND_MAX) * 10.0) - 5.0, + ((rand()/(float)RAND_MAX) * 40.0) - 45.0); + } + glEnd(); + glEndList(); + + glEnable(GL_DEPTH_TEST); + glEnable(GL_POINT_SMOOTH); + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + glPointSize(psize); + glGetFloatv(GL_POINT_SIZE_MAX_EXT, pmax); + + glPointParameterfvEXT (GL_DISTANCE_ATTENUATION_EXT, linear); + glPointParameterfEXT (GL_POINT_FADE_THRESHOLD_SIZE_EXT, 2.0); +} + +static void display(void) +{ + glClear (GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glCallList (1); + glutSwapBuffers (); +} + +static void reshape (int w, int h) +{ + glViewport (0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode (GL_PROJECTION); + glLoadIdentity (); + gluPerspective (35.0, 1.0, 0.25, 200.0); + glMatrixMode (GL_MODELVIEW); + glTranslatef (0.0, 0.0, -10.0); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 'b': + glMatrixMode (GL_MODELVIEW); + glTranslatef (0.0, 0.0, -0.5); + glutPostRedisplay(); + break; + case 'c': + glPointParameterfvEXT (GL_DISTANCE_ATTENUATION_EXT, constant); + glutPostRedisplay(); + break; + case 'f': + glMatrixMode (GL_MODELVIEW); + glTranslatef (0.0, 0.0, 0.5); + glutPostRedisplay(); + break; + case 'l': + glPointParameterfvEXT (GL_DISTANCE_ATTENUATION_EXT, linear); + glutPostRedisplay(); + break; + case 'q': + glPointParameterfvEXT (GL_DISTANCE_ATTENUATION_EXT, quadratic); + glutPostRedisplay(); + break; + case '+': + if (psize < (pmax[0] + 1.0)) + psize = psize + 1.0; + glPointSize (psize); + glutPostRedisplay(); + break; + case '-': + if (psize >= 2.0) + psize = psize - 1.0; + glPointSize (psize); + glutPostRedisplay(); + break; + case 27: + exit(0); + break; + } +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode (GLUT_RGB | GLUT_DOUBLE | GLUT_DEPTH | GLUT_MULTISAMPLE); + glutInitWindowSize (500, 500); + glutInitWindowPosition (100, 100); + glutCreateWindow (argv[0]); + glewInit(); + init (); + glutDisplayFunc (display); + glutReshapeFunc (reshape); + glutKeyboardFunc (keyboard); + glutMainLoop(); + return 0; +} diff --git a/progs/redbook/shadowmap.c b/progs/redbook/shadowmap.c new file mode 100644 index 0000000000..f37191d9ff --- /dev/null +++ b/progs/redbook/shadowmap.c @@ -0,0 +1,352 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +#include <math.h> +#include <stdio.h> +#include <stdlib.h> +#include <GL/glew.h> +#include <GL/glut.h> +/*#include "helpers.h"*/ + +#define SHADOW_MAP_WIDTH 256 +#define SHADOW_MAP_HEIGHT 256 + +#define PI 3.14159265359 + +GLdouble fovy = 60.0; +GLdouble nearPlane = 10.0; +GLdouble farPlane = 100.0; + +GLfloat angle = 0.0; +GLfloat torusAngle = 0.0; + +GLfloat lightPos[] = { 25.0, 25.0, 25.0, 1.0 }; +GLfloat lookat[] = { 0.0, 0.0, 0.0 }; +GLfloat up[] = { 0.0, 0.0, 1.0 }; + +GLboolean showShadow = GL_FALSE; + +static void +init( void ) +{ + GLfloat white[] = { 1.0, 1.0, 1.0, 1.0 }; + + glTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, + SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, 0, + GL_DEPTH_COMPONENT, GL_UNSIGNED_BYTE, NULL ); + + glLightfv( GL_LIGHT0, GL_POSITION, lightPos ); + glLightfv( GL_LIGHT0, GL_SPECULAR, white ); + glLightfv( GL_LIGHT0, GL_DIFFUSE, white ); + + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, GL_LEQUAL ); + glTexParameteri( GL_TEXTURE_2D, GL_DEPTH_TEXTURE_MODE, GL_LUMINANCE ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, + GL_COMPARE_R_TO_TEXTURE ); + + glTexGeni( GL_S, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + glTexGeni( GL_T, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + glTexGeni( GL_R, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + glTexGeni( GL_Q, GL_TEXTURE_GEN_MODE, GL_OBJECT_LINEAR ); + + glColorMaterial( GL_FRONT_AND_BACK, GL_AMBIENT_AND_DIFFUSE ); + + glCullFace( GL_BACK ); + + glEnable( GL_DEPTH_TEST ); + glEnable( GL_LIGHT0 ); + glEnable( GL_LIGHTING ); + glEnable( GL_TEXTURE_2D ); + glEnable( GL_TEXTURE_GEN_S ); + glEnable( GL_TEXTURE_GEN_T ); + glEnable( GL_TEXTURE_GEN_R ); + glEnable( GL_TEXTURE_GEN_Q ); + glEnable( GL_COLOR_MATERIAL ); + glEnable( GL_CULL_FACE ); +} + +static void +reshape( int width, int height ) +{ + glViewport( 0, 0, width, height ); + + glMatrixMode( GL_PROJECTION ); + glLoadIdentity(); + gluPerspective( fovy, (GLdouble) width/height, nearPlane, farPlane ); + glMatrixMode( GL_MODELVIEW ); +} + +static void +idle( void ) +{ + angle += PI / 10000; + torusAngle += .1; + glutPostRedisplay(); +} + +static void +keyboard( unsigned char key, int x, int y ) +{ + switch( key ) { + case 27: /* Escape */ + exit( 0 ); + break; + + case 't': { + static GLboolean textureOn = GL_TRUE; + textureOn = !textureOn; + if ( textureOn ) + glEnable( GL_TEXTURE_2D ); + else + glDisable( GL_TEXTURE_2D ); + } + break; + + case 'm': { + static GLboolean compareMode = GL_TRUE; + compareMode = !compareMode; + printf( "Compare mode %s\n", compareMode ? "On" : "Off" ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_MODE, + compareMode ? GL_COMPARE_R_TO_TEXTURE : GL_NONE ); + } + break; + + case 'f': { + static GLboolean funcMode = GL_TRUE; + funcMode = !funcMode; + printf( "Operator %s\n", funcMode ? "GL_LEQUAL" : "GL_GEQUAL" ); + glTexParameteri( GL_TEXTURE_2D, GL_TEXTURE_COMPARE_FUNC, + funcMode ? GL_LEQUAL : GL_GEQUAL ); + } + break; + + case 's': + showShadow = !showShadow; + break; + + case 'p': { + static GLboolean animate = GL_TRUE; + animate = !animate; + glutIdleFunc( animate ? idle : NULL ); + } + break; + } + + glutPostRedisplay(); +} + +static void +transposeMatrix( GLfloat m[16] ) +{ + GLfloat tmp; +#define Swap( a, b ) tmp = a; a = b; b = tmp + Swap( m[1], m[4] ); + Swap( m[2], m[8] ); + Swap( m[3], m[12] ); + Swap( m[6], m[9] ); + Swap( m[7], m[13] ); + Swap( m[11], m[14] ); +#undef Swap +} + +static void +drawObjects( GLboolean shadowRender ) +{ + GLboolean textureOn = glIsEnabled( GL_TEXTURE_2D ); + + if ( shadowRender ) + glDisable( GL_TEXTURE_2D ); + + if ( !shadowRender ) { + glNormal3f( 0, 0, 1 ); + glColor3f( 1, 1, 1 ); + glRectf( -20.0, -20.0, 20.0, 20.0 ); + } + + glPushMatrix(); + glTranslatef( 11, 11, 11 ); + glRotatef( 54.73, -5, 5, 0 ); + glRotatef( torusAngle, 1, 0, 0 ); + glColor3f( 1, 0, 0 ); + glutSolidTorus( 1, 4, 8, 36 ); + glPopMatrix(); + + glPushMatrix(); + glTranslatef( 2, 2, 2 ); + glColor3f( 0, 0, 1 ); + glutSolidCube( 4 ); + glPopMatrix(); + + glPushMatrix(); + glTranslatef( lightPos[0], lightPos[1], lightPos[2] ); + glColor3f( 1, 1, 1 ); + glutWireSphere( 0.5, 6, 6 ); + glPopMatrix(); + + if ( shadowRender && textureOn ) + glEnable( GL_TEXTURE_2D ); +} + +static void +generateShadowMap( void ) +{ + GLint viewport[4]; + GLfloat lightPos[4]; + + glGetLightfv( GL_LIGHT0, GL_POSITION, lightPos ); + glGetIntegerv( GL_VIEWPORT, viewport ); + + glViewport( 0, 0, SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT ); + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glMatrixMode( GL_PROJECTION ); + glPushMatrix(); + glLoadIdentity(); + gluPerspective( 80.0, 1.0, 10.0, 1000.0 ); + glMatrixMode( GL_MODELVIEW ); + + glPushMatrix(); + glLoadIdentity(); + gluLookAt( lightPos[0], lightPos[1], lightPos[2], + lookat[0], lookat[1], lookat[2], + up[0], up[1], up[2] ); + + drawObjects( GL_TRUE ); + + glPopMatrix(); + glMatrixMode( GL_PROJECTION ); + glPopMatrix(); + glMatrixMode( GL_MODELVIEW ); + + glCopyTexImage2D( GL_TEXTURE_2D, 0, GL_DEPTH_COMPONENT, 0, 0, + SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, 0 ); + + glViewport( viewport[0], viewport[1], viewport[2], viewport[3] ); + + if ( showShadow ) { + GLfloat depthImage[SHADOW_MAP_WIDTH][SHADOW_MAP_HEIGHT]; + glReadPixels( 0, 0, SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, + GL_DEPTH_COMPONENT, GL_FLOAT, depthImage ); + glWindowPos2f( viewport[2]/2, 0 ); + glDrawPixels( SHADOW_MAP_WIDTH, SHADOW_MAP_HEIGHT, GL_LUMINANCE, + GL_FLOAT, depthImage ); + glutSwapBuffers(); + } +} + +static void +generateTextureMatrix( void ) +{ + GLfloat tmpMatrix[16]; + + /* + * Set up projective texture matrix. We use the GL_MODELVIEW matrix + * stack and OpenGL matrix commands to make the matrix. + */ + glPushMatrix(); + glLoadIdentity(); + glTranslatef( 0.5, 0.5, 0.0 ); + glScalef( 0.5, 0.5, 1.0 ); + gluPerspective( 60.0, 1.0, 1.0, 1000.0 ); + gluLookAt( lightPos[0], lightPos[1], lightPos[2], + lookat[0], lookat[1], lookat[2], + up[0], up[1], up[2] ); + glGetFloatv( GL_MODELVIEW_MATRIX, tmpMatrix ); + glPopMatrix(); + + transposeMatrix( tmpMatrix ); + + glTexGenfv( GL_S, GL_OBJECT_PLANE, &tmpMatrix[0] ); + glTexGenfv( GL_T, GL_OBJECT_PLANE, &tmpMatrix[4] ); + glTexGenfv( GL_R, GL_OBJECT_PLANE, &tmpMatrix[8] ); + glTexGenfv( GL_Q, GL_OBJECT_PLANE, &tmpMatrix[12] ); +} + +static void +display( void ) +{ + GLfloat radius = 30; + + generateShadowMap(); + generateTextureMatrix(); + + if ( showShadow ) + return; + + glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT ); + + glPushMatrix(); + gluLookAt( radius*cos(angle), radius*sin(angle), 30, + lookat[0], lookat[1], lookat[2], + up[0], up[1], up[2] ); + drawObjects( GL_FALSE ); + glPopMatrix(); + + glutSwapBuffers(); +} + +int +main( int argc, char** argv ) +{ + glutInit( &argc, argv ); + glutInitDisplayMode( GLUT_RGBA | GLUT_DEPTH | GLUT_DOUBLE ); + glutInitWindowSize( 512, 512 ); + glutInitWindowPosition( 100, 100 ); + glutCreateWindow( argv[0] ); + glewInit(); + + init(); + + glutDisplayFunc( display ); + glutReshapeFunc( reshape ); + glutKeyboardFunc( keyboard ); + glutIdleFunc( idle ); + + glutMainLoop(); + + return 0; +} diff --git a/progs/redbook/surfpoints.c b/progs/redbook/surfpoints.c new file mode 100644 index 0000000000..094f0dada8 --- /dev/null +++ b/progs/redbook/surfpoints.c @@ -0,0 +1,280 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* + * surfpoints.c + * This program is a modification of the earlier surface.c + * program. The vertex data are not directly rendered, + * but are instead passed to the callback function. + * The values of the tessellated vertices are printed + * out there. + * + * This program draws a NURBS surface in the shape of a + * symmetrical hill. The 'c' keyboard key allows you to + * toggle the visibility of the control points themselves. + * Note that some of the control points are hidden by the + * surface itself. + */ +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + +#ifdef GLU_VERSION_1_3 + +#ifndef CALLBACK +#define CALLBACK +#endif + +GLfloat ctlpoints[4][4][3]; +int showPoints = 0; + +GLUnurbsObj *theNurb; + +/* + * Initializes the control points of the surface to a small hill. + * The control points range from -3 to +3 in x, y, and z + */ +static void init_surface(void) +{ + int u, v; + for (u = 0; u < 4; u++) { + for (v = 0; v < 4; v++) { + ctlpoints[u][v][0] = 2.0*((GLfloat)u - 1.5); + ctlpoints[u][v][1] = 2.0*((GLfloat)v - 1.5); + + if ( (u == 1 || u == 2) && (v == 1 || v == 2)) + ctlpoints[u][v][2] = 3.0; + else + ctlpoints[u][v][2] = -3.0; + } + } +} + +static void CALLBACK nurbsError(GLenum errorCode) +{ + const GLubyte *estring; + + estring = gluErrorString(errorCode); + fprintf (stderr, "Nurbs Error: %s\n", estring); + exit (0); +} + +static void CALLBACK beginCallback(GLenum whichType) +{ + glBegin (whichType); /* resubmit rendering directive */ + printf ("glBegin("); + switch (whichType) { /* print diagnostic message */ + case GL_LINES: + printf ("GL_LINES)\n"); + break; + case GL_LINE_LOOP: + printf ("GL_LINE_LOOP)\n"); + break; + case GL_LINE_STRIP: + printf ("GL_LINE_STRIP)\n"); + break; + case GL_TRIANGLES: + printf ("GL_TRIANGLES)\n"); + break; + case GL_TRIANGLE_STRIP: + printf ("GL_TRIANGLE_STRIP)\n"); + break; + case GL_TRIANGLE_FAN: + printf ("GL_TRIANGLE_FAN)\n"); + break; + case GL_QUADS: + printf ("GL_QUADS)\n"); + break; + case GL_QUAD_STRIP: + printf ("GL_QUAD_STRIP)\n"); + break; + case GL_POLYGON: + printf ("GL_POLYGON)\n"); + break; + default: + break; + } +} + +static void CALLBACK endCallback() +{ + glEnd(); /* resubmit rendering directive */ + printf ("glEnd()\n"); +} + +static void CALLBACK vertexCallback(GLfloat *vertex) +{ + glVertex3fv(vertex); /* resubmit rendering directive */ + printf ("glVertex3f (%5.3f, %5.3f, %5.3f)\n", + vertex[0], vertex[1], vertex[2]); +} + +static void CALLBACK normalCallback(GLfloat *normal) +{ + glNormal3fv(normal); /* resubmit rendering directive */ + printf ("glNormal3f (%5.3f, %5.3f, %5.3f)\n", + normal[0], normal[1], normal[2]); +} + +/* Initialize material property and depth buffer. + */ +static void init(void) +{ + GLfloat mat_diffuse[] = { 0.7, 0.7, 0.7, 1.0 }; + GLfloat mat_specular[] = { 1.0, 1.0, 1.0, 1.0 }; + GLfloat mat_shininess[] = { 100.0 }; + + glClearColor (0.0, 0.0, 0.0, 0.0); + glMaterialfv(GL_FRONT, GL_DIFFUSE, mat_diffuse); + glMaterialfv(GL_FRONT, GL_SPECULAR, mat_specular); + glMaterialfv(GL_FRONT, GL_SHININESS, mat_shininess); + + glEnable(GL_LIGHTING); + glEnable(GL_LIGHT0); + glEnable(GL_DEPTH_TEST); + glEnable(GL_AUTO_NORMAL); + glEnable(GL_NORMALIZE); + + init_surface(); + + theNurb = gluNewNurbsRenderer(); + gluNurbsProperty(theNurb, GLU_NURBS_MODE, + GLU_NURBS_TESSELLATOR); + gluNurbsProperty(theNurb, GLU_SAMPLING_TOLERANCE, 25.0); + gluNurbsProperty(theNurb, GLU_DISPLAY_MODE, GLU_FILL); + gluNurbsCallback(theNurb, GLU_ERROR, nurbsError); + gluNurbsCallback(theNurb, GLU_NURBS_BEGIN, beginCallback); + gluNurbsCallback(theNurb, GLU_NURBS_VERTEX, vertexCallback); + gluNurbsCallback(theNurb, GLU_NURBS_NORMAL, normalCallback); + gluNurbsCallback(theNurb, GLU_NURBS_END, endCallback); + +} + +static void display(void) +{ + GLfloat knots[8] = {0.0, 0.0, 0.0, 0.0, 1.0, 1.0, 1.0, 1.0}; + int i, j; + + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + + glPushMatrix(); + glRotatef(330.0, 1.,0.,0.); + glScalef (0.5, 0.5, 0.5); + + gluBeginSurface(theNurb); + gluNurbsSurface(theNurb, + 8, knots, 8, knots, + 4 * 3, 3, &ctlpoints[0][0][0], + 4, 4, GL_MAP2_VERTEX_3); + gluEndSurface(theNurb); + + if (showPoints) { + glPointSize(5.0); + glDisable(GL_LIGHTING); + glColor3f(1.0, 1.0, 0.0); + glBegin(GL_POINTS); + for (i = 0; i < 4; i++) { + for (j = 0; j < 4; j++) { + glVertex3f(ctlpoints[i][j][0], + ctlpoints[i][j][1], ctlpoints[i][j][2]); + } + } + glEnd(); + glEnable(GL_LIGHTING); + } + glPopMatrix(); + glFlush(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective (45.0, (GLdouble)w/(GLdouble)h, 3.0, 8.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef (0.0, 0.0, -5.0); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 'c': + case 'C': + showPoints = !showPoints; + glutPostRedisplay(); + break; + case 27: + exit(0); + break; + default: + break; + } +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize (500, 500); + glutInitWindowPosition (100, 100); + glutCreateWindow(argv[0]); + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutKeyboardFunc (keyboard); + glutMainLoop(); + return 0; +} + +#else +int main(int argc, char** argv) +{ + fprintf (stderr, "This program demonstrates a feature which is introduced in the\n"); + fprintf (stderr, "OpenGL Utility Library (GLU) Version 1.3.\n"); + fprintf (stderr, "If your implementation of GLU has the right extensions,\n"); + fprintf (stderr, "you may be able to modify this program to make it run.\n"); + return 0; +} +#endif + diff --git a/progs/redbook/texture3d.c b/progs/redbook/texture3d.c new file mode 100644 index 0000000000..c7b77c1cae --- /dev/null +++ b/progs/redbook/texture3d.c @@ -0,0 +1,163 @@ +/* + * Copyright (c) 1993-2003, Silicon Graphics, Inc. + * All Rights Reserved + * + * Permission to use, copy, modify, and distribute this software for any + * purpose and without fee is hereby granted, provided that the above + * copyright notice appear in all copies and that both the copyright + * notice and this permission notice appear in supporting documentation, + * and that the name of Silicon Graphics, Inc. not be used in + * advertising or publicity pertaining to distribution of the software + * without specific, written prior permission. + * + * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" AND + * WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, + * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR + * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON + * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, + * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY KIND, + * OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, LOSS OF + * PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF THIRD + * PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN ADVISED OF + * THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON ANY THEORY OF + * LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE POSSESSION, USE + * OR PERFORMANCE OF THIS SOFTWARE. + * + * US Government Users Restricted Rights + * Use, duplication, or disclosure by the Government is subject to + * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph + * (c)(1)(ii) of the Rights in Technical Data and Computer Software + * clause at DFARS 252.227-7013 and/or in similar or successor clauses + * in the FAR or the DOD or NASA FAR Supplement. Unpublished - rights + * reserved under the copyright laws of the United States. + * + * Contractor/manufacturer is: + * Silicon Graphics, Inc. + * 1500 Crittenden Lane + * Mountain View, CA 94043 + * United State of America + * + * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. + */ + +/* texture3d.c + * This program demonstrates using a three-dimensional texture. + * It creates a 3D texture and then renders two rectangles + * with different texture coordinates to obtain different + * "slices" of the 3D texture. + */ +#include <GL/glew.h> +#include <GL/glut.h> +#include <stdlib.h> +#include <stdio.h> + +#ifdef GL_VERSION_1_2 +#define iWidth 16 +#define iHeight 16 +#define iDepth 16 + +static GLubyte image[iDepth][iHeight][iWidth][3]; +static GLuint texName; + +/* Create a 16x16x16x3 array with different color values in + * each array element [r, g, b]. Values range from 0 to 255. + */ + +static void makeImage(void) +{ + int s, t, r; + + for (s = 0; s < 16; s++) + for (t = 0; t < 16; t++) + for (r = 0; r < 16; r++) { + image[r][t][s][0] = (GLubyte) (s * 17); + image[r][t][s][1] = (GLubyte) (t * 17); + image[r][t][s][2] = (GLubyte) (r * 17); + } +} + +static void init(void) +{ + glClearColor (0.0, 0.0, 0.0, 0.0); + glShadeModel(GL_FLAT); + glEnable(GL_DEPTH_TEST); + + makeImage(); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + + glGenTextures(1, &texName); + glBindTexture(GL_TEXTURE_3D, texName); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_S, GL_CLAMP); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_T, GL_CLAMP); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_WRAP_R, GL_CLAMP); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MAG_FILTER, + GL_NEAREST); + glTexParameteri(GL_TEXTURE_3D, GL_TEXTURE_MIN_FILTER, + GL_NEAREST); + glTexImage3D(GL_TEXTURE_3D, 0, GL_RGB, iWidth, iHeight, + iDepth, 0, GL_RGB, GL_UNSIGNED_BYTE, image); + glEnable(GL_TEXTURE_3D); +} + +static void display(void) +{ + glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); + glBegin(GL_QUADS); + glTexCoord3f(0.0, 0.0, 0.0); glVertex3f(-2.25, -1.0, 0.0); + glTexCoord3f(0.0, 1.0, 0.0); glVertex3f(-2.25, 1.0, 0.0); + glTexCoord3f(1.0, 1.0, 1.0); glVertex3f(-0.25, 1.0, 0.0); + glTexCoord3f(1.0, 0.0, 1.0); glVertex3f(-0.25, -1.0, 0.0); + + glTexCoord3f(0.0, 0.0, 1.0); glVertex3f(0.25, -1.0, 0.0); + glTexCoord3f(0.0, 1.0, 1.0); glVertex3f(0.25, 1.0, 0.0); + glTexCoord3f(1.0, 1.0, 0.0); glVertex3f(2.25, 1.0, 0.0); + glTexCoord3f(1.0, 0.0, 0.0); glVertex3f(2.25, -1.0, 0.0); + glEnd(); + glFlush(); +} + +static void reshape(int w, int h) +{ + glViewport(0, 0, (GLsizei) w, (GLsizei) h); + glMatrixMode(GL_PROJECTION); + glLoadIdentity(); + gluPerspective(60.0, (GLfloat) w/(GLfloat) h, 1.0, 30.0); + glMatrixMode(GL_MODELVIEW); + glLoadIdentity(); + glTranslatef(0.0, 0.0, -4.0); +} + +static void keyboard(unsigned char key, int x, int y) +{ + switch (key) { + case 27: + exit(0); + break; + } +} + +int main(int argc, char** argv) +{ + glutInit(&argc, argv); + glutInitDisplayMode(GLUT_SINGLE | GLUT_RGB | GLUT_DEPTH); + glutInitWindowSize(250, 250); + glutInitWindowPosition(100, 100); + glutCreateWindow(argv[0]); + glewInit(); + init(); + glutReshapeFunc(reshape); + glutDisplayFunc(display); + glutKeyboardFunc (keyboard); + glutMainLoop(); + return 0; +} +#else +int main(int argc, char** argv) +{ + fprintf (stderr, "This program demonstrates a feature which is not in OpenGL Version 1.0 or 1.1.\n"); + fprintf (stderr, "If your implementation of OpenGL has the right extensions,\n"); + fprintf (stderr, "you may be able to modify this program to make it run.\n"); + return 0; +} +#endif + diff --git a/progs/tests/vpeval.c b/progs/tests/vpeval.c index 3e8a732df5..a4024b5336 100644 --- a/progs/tests/vpeval.c +++ b/progs/tests/vpeval.c @@ -145,6 +145,11 @@ myinit(int argc, char *argv[]) printf("Using vertex program attribs? %s\n", program ? "yes" : "no"); + if (program && !glutExtensionSupported("GL_NV_vertex_program")) { + printf("Sorry, this requires GL_NV_vertex_program\n"); + exit(1); + } + if (!program) { glMap2f(GL_MAP2_VERTEX_4, 0.0, 1.0, 4, 4, diff --git a/progs/tests/vptest1.c b/progs/tests/vptest1.c index 6e32b03346..d83f9cae37 100644 --- a/progs/tests/vptest1.c +++ b/progs/tests/vptest1.c @@ -113,6 +113,11 @@ static void Init( void ) GLuint progs[5]; + if (!glutExtensionSupported("GL_NV_vertex_program")) { + printf("Sorry, this program requires GL_NV_vertex_program\n"); + exit(1); + } + glGenProgramsNV(2, progs); assert(progs[0]); assert(progs[1]); diff --git a/progs/tests/vptest2.c b/progs/tests/vptest2.c index 4161b03a67..89cd6b1458 100644 --- a/progs/tests/vptest2.c +++ b/progs/tests/vptest2.c @@ -144,6 +144,12 @@ int main( int argc, char *argv[] ) glutReshapeFunc( Reshape ); glutKeyboardFunc( Key ); glutDisplayFunc( Display ); + + if (!glutExtensionSupported("GL_NV_vertex_program")) { + printf("Sorry, this program requires GL_NV_vertex_program\n"); + exit(1); + } + Test1(); Test2(); Test3(); diff --git a/progs/tests/vptest3.c b/progs/tests/vptest3.c index 4e4bfee31d..58ce227e6e 100644 --- a/progs/tests/vptest3.c +++ b/progs/tests/vptest3.c @@ -93,6 +93,11 @@ static void Init( void ) #endif "END\n"; + if (!glutExtensionSupported("GL_NV_vertex_program")) { + printf("Sorry, this program requires GL_NV_vertex_program\n"); + exit(1); + } + glLoadProgramNV(GL_VERTEX_PROGRAM_NV, 1, strlen(prog1), (const GLubyte *) prog1); diff --git a/scons/gallium.py b/scons/gallium.py index a40a957191..925effc25d 100644 --- a/scons/gallium.py +++ b/scons/gallium.py @@ -155,7 +155,9 @@ def generate(env): # different scons versions building the same source file env['build'] = build_dir env.SConsignFile(os.path.join(build_dir, '.sconsign')) - env.CacheDir('build/cache') + if 'SCONS_CACHE_DIR' in os.environ: + print 'scons: Using build cache in %s.' % (os.environ['SCONS_CACHE_DIR'],) + env.CacheDir(os.environ['SCONS_CACHE_DIR']) env['CONFIGUREDIR'] = os.path.join(build_dir, 'conf') env['CONFIGURELOG'] = os.path.join(os.path.abspath(build_dir), 'config.log') @@ -177,8 +179,9 @@ def generate(env): '_WINDOWS', #'_UNICODE', #'UNICODE', - ('_WIN32_WINNT', '0x0501'), # minimum required OS version - ('WINVER', '0x0501'), + # http://msdn.microsoft.com/en-us/library/aa383745.aspx + ('_WIN32_WINNT', '0x0601'), + ('WINVER', '0x0601'), ] if msvc and env['toolchain'] != 'winddk': cppdefines += [ diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c index 364ad9c458..2de1ac3318 100644 --- a/src/egl/main/eglapi.c +++ b/src/egl/main/eglapi.c @@ -70,98 +70,55 @@ /** - * This is typically the first EGL function that an application calls. - * We initialize our global vars and create a private _EGLDisplay object. + * Macros to help return an API entrypoint. + * + * These macros will unlock the display and record the error code. */ -EGLDisplay EGLAPIENTRY -eglGetDisplay(EGLNativeDisplayType nativeDisplay) -{ - _EGLDisplay *dpy; - dpy = _eglFindDisplay(nativeDisplay); - if (!dpy) { - dpy = _eglNewDisplay(nativeDisplay); - if (dpy) - _eglLinkDisplay(dpy); - } - return _eglGetDisplayHandle(dpy); -} +#define _EGL_ERROR(disp, err, ret) \ + ({ \ + if (disp) \ + _eglUnlockDisplay(disp); \ + /* EGL error codes are non-zero */ \ + if (err) \ + _eglError(err, __FUNCTION__); \ + ret; \ + }) +#define _EGL_SUCCESS(disp, ret) _EGL_ERROR(disp, EGL_SUCCESS, ret) +/* record EGL_SUCCESS only when ret evaluates to true */ +#define _EGL_EVAL(disp, ret) _EGL_ERROR(disp, (ret) ? EGL_SUCCESS : 0, ret) /** - * This is typically the second EGL function that an application calls. - * Here we load/initialize the actual hardware driver. + * A bunch of macros and checks to simplify error checking. */ -EGLBoolean EGLAPIENTRY -eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - EGLint major_int, minor_int; - - if (!disp) - return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); - - if (!disp->Initialized) { - _EGLDriver *drv = disp->Driver; - - if (!drv) { - _eglPreloadDrivers(); - drv = _eglMatchDriver(disp); - if (!drv) - return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); - } - - /* Initialize the particular display now */ - if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) - return _eglError(EGL_NOT_INITIALIZED, __FUNCTION__); - - disp->APImajor = major_int; - disp->APIminor = minor_int; - snprintf(disp->Version, sizeof(disp->Version), - "%d.%d (%s)", major_int, minor_int, drv->Name); +#define _EGL_CHECK_DISPLAY(disp, ret) \ + ({ \ + _EGLDriver *__drv = _eglCheckDisplay(disp, __FUNCTION__); \ + if (!__drv) \ + return _EGL_ERROR(disp, 0, ret); \ + __drv; \ + }) + + +#define _EGL_CHECK_OBJECT(disp, type, obj, ret) \ + ({ \ + _EGLDriver *__drv = _eglCheck ## type(disp, obj, __FUNCTION__); \ + if (!__drv) \ + return _EGL_ERROR(disp, 0, ret); \ + __drv; \ + }) +#define _EGL_CHECK_SURFACE(disp, surf, ret) \ + _EGL_CHECK_OBJECT(disp, Surface, surf, ret) +#define _EGL_CHECK_CONTEXT(disp, context, ret) \ + _EGL_CHECK_OBJECT(disp, Context, context, ret) +#define _EGL_CHECK_CONFIG(disp, conf, ret) \ + _EGL_CHECK_OBJECT(disp, Config, conf, ret) +#define _EGL_CHECK_SCREEN(disp, scrn, ret) \ + _EGL_CHECK_OBJECT(disp, Screen, scrn, ret) +#define _EGL_CHECK_MODE(disp, m, ret) \ + _EGL_CHECK_OBJECT(disp, Mode, m, ret) - /* limit to APIs supported by core */ - disp->ClientAPIsMask &= _EGL_API_ALL_BITS; - disp->Driver = drv; - disp->Initialized = EGL_TRUE; - } else { - major_int = disp->APImajor; - minor_int = disp->APIminor; - } - - /* Update applications version of major and minor if not NULL */ - if ((major != NULL) && (minor != NULL)) { - *major = major_int; - *minor = minor_int; - } - - return EGL_TRUE; -} - - -EGLBoolean EGLAPIENTRY -eglTerminate(EGLDisplay dpy) -{ - _EGLDisplay *disp = _eglLookupDisplay(dpy); - - if (!disp) - return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); - - if (disp->Initialized) { - _EGLDriver *drv = disp->Driver; - - drv->API.Terminate(drv, disp); - /* do not reset disp->Driver */ - disp->Initialized = EGL_FALSE; - } - - return EGL_TRUE; -} - - -/** - * A bunch of check functions and declare macros to simply error checking. - */ static INLINE _EGLDriver * _eglCheckDisplay(_EGLDisplay *disp, const char *msg) { @@ -219,38 +176,6 @@ _eglCheckConfig(_EGLDisplay *disp, _EGLConfig *conf, const char *msg) } -#define _EGL_DECLARE_DD(dpy) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckDisplay(disp, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) - - -#define _EGL_DECLARE_DD_AND_SURFACE(dpy, surface) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLSurface *surf = _eglLookupSurface((surface), disp); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckSurface(disp, surf, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) - - -#define _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLContext *context = _eglLookupContext((ctx), disp); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckContext(disp, context, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) - - #ifdef EGL_MESA_screen_surface @@ -282,36 +207,127 @@ _eglCheckMode(_EGLDisplay *disp, _EGLMode *m, const char *msg) } -#define _EGL_DECLARE_DD_AND_SCREEN(dpy, screen) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLScreen *scrn = _eglLookupScreen((screen), disp); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckScreen(disp, scrn, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) +#endif /* EGL_MESA_screen_surface */ -#define _EGL_DECLARE_DD_AND_MODE(dpy, mode) \ - _EGLDisplay *disp = _eglLookupDisplay(dpy); \ - _EGLMode *m = _eglLookupMode((mode), disp); \ - _EGLDriver *drv; \ - do { \ - drv = _eglCheckMode(disp, m, __FUNCTION__); \ - if (!drv) \ - return EGL_FALSE; \ - } while (0) +/** + * Lookup and lock a display. + */ +static INLINE _EGLDisplay * +_eglLockDisplay(EGLDisplay display) +{ + _EGLDisplay *dpy = _eglLookupDisplay(display); + if (dpy) + _eglLockMutex(&dpy->Mutex); + return dpy; +} -#endif /* EGL_MESA_screen_surface */ +/** + * Unlock a display. + */ +static INLINE void +_eglUnlockDisplay(_EGLDisplay *dpy) +{ + _eglUnlockMutex(&dpy->Mutex); +} + + +/** + * This is typically the first EGL function that an application calls. + * It associates a private _EGLDisplay object to the native display. + */ +EGLDisplay EGLAPIENTRY +eglGetDisplay(EGLNativeDisplayType nativeDisplay) +{ + _EGLDisplay *dpy = _eglFindDisplay(nativeDisplay); + return _eglGetDisplayHandle(dpy); +} + + +/** + * This is typically the second EGL function that an application calls. + * Here we load/initialize the actual hardware driver. + */ +EGLBoolean EGLAPIENTRY +eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + EGLint major_int, minor_int; + + if (!disp) + return _EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); + + if (!disp->Initialized) { + _EGLDriver *drv = disp->Driver; + + if (!drv) { + _eglPreloadDrivers(); + drv = _eglMatchDriver(disp); + if (!drv) + return _EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); + } + + /* Initialize the particular display now */ + if (!drv->API.Initialize(drv, disp, &major_int, &minor_int)) + return _EGL_ERROR(disp, EGL_NOT_INITIALIZED, EGL_FALSE); + + disp->APImajor = major_int; + disp->APIminor = minor_int; + snprintf(disp->Version, sizeof(disp->Version), + "%d.%d (%s)", major_int, minor_int, drv->Name); + + /* limit to APIs supported by core */ + disp->ClientAPIsMask &= _EGL_API_ALL_BITS; + + disp->Driver = drv; + disp->Initialized = EGL_TRUE; + } else { + major_int = disp->APImajor; + minor_int = disp->APIminor; + } + + /* Update applications version of major and minor if not NULL */ + if ((major != NULL) && (minor != NULL)) { + *major = major_int; + *minor = minor_int; + } + + return _EGL_SUCCESS(disp, EGL_TRUE); +} + + +EGLBoolean EGLAPIENTRY +eglTerminate(EGLDisplay dpy) +{ + _EGLDisplay *disp = _eglLockDisplay(dpy); + + if (!disp) + return _EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE); + + if (disp->Initialized) { + _EGLDriver *drv = disp->Driver; + + drv->API.Terminate(drv, disp); + /* do not reset disp->Driver */ + disp->Initialized = EGL_FALSE; + } + + return _EGL_SUCCESS(disp, EGL_TRUE); +} const char * EGLAPIENTRY eglQueryString(EGLDisplay dpy, EGLint name) { - _EGL_DECLARE_DD(dpy); - return drv->API.QueryString(drv, disp, name); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + const char *ret; + + drv = _EGL_CHECK_DISPLAY(disp, NULL); + ret = drv->API.QueryString(drv, disp, name); + + return _EGL_EVAL(disp, ret); } @@ -319,8 +335,14 @@ EGLBoolean EGLAPIENTRY eglGetConfigs(EGLDisplay dpy, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - _EGL_DECLARE_DD(dpy); - return drv->API.GetConfigs(drv, disp, configs, config_size, num_config); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE); + ret = drv->API.GetConfigs(drv, disp, configs, config_size, num_config); + + return _EGL_EVAL(disp, ret); } @@ -328,9 +350,15 @@ EGLBoolean EGLAPIENTRY eglChooseConfig(EGLDisplay dpy, const EGLint *attrib_list, EGLConfig *configs, EGLint config_size, EGLint *num_config) { - _EGL_DECLARE_DD(dpy); - return drv->API.ChooseConfig(drv, disp, attrib_list, configs, + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE); + ret = drv->API.ChooseConfig(drv, disp, attrib_list, configs, config_size, num_config); + + return _EGL_EVAL(disp, ret); } @@ -338,15 +366,15 @@ EGLBoolean EGLAPIENTRY eglGetConfigAttrib(EGLDisplay dpy, EGLConfig config, EGLint attribute, EGLint *value) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; + EGLBoolean ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_FALSE; + drv = _EGL_CHECK_CONFIG(disp, conf, EGL_FALSE); + ret = drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); - return drv->API.GetConfigAttrib(drv, disp, conf, attribute, value); + return _EGL_EVAL(disp, ret); } @@ -354,34 +382,37 @@ EGLContext EGLAPIENTRY eglCreateContext(EGLDisplay dpy, EGLConfig config, EGLContext share_list, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLContext *share = _eglLookupContext(share_list, disp); _EGLDriver *drv; _EGLContext *context; + EGLContext ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_CONTEXT; - if (!share && share_list != EGL_NO_CONTEXT) { - _eglError(EGL_BAD_CONTEXT, __FUNCTION__); - return EGL_NO_CONTEXT; - } + drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_CONTEXT); + if (!share && share_list != EGL_NO_CONTEXT) + return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_CONTEXT); context = drv->API.CreateContext(drv, disp, conf, share, attrib_list); - if (context) - return _eglLinkContext(context, disp); - else - return EGL_NO_CONTEXT; + ret = (context) ? _eglLinkContext(context, disp) : EGL_NO_CONTEXT; + + return _EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglDestroyContext(EGLDisplay dpy, EGLContext ctx) { - _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLContext *context = _eglLookupContext(ctx, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE); _eglUnlinkContext(context); - return drv->API.DestroyContext(drv, disp, context); + ret = drv->API.DestroyContext(drv, disp, context); + + return _EGL_EVAL(disp, ret); } @@ -389,32 +420,35 @@ EGLBoolean EGLAPIENTRY eglMakeCurrent(EGLDisplay dpy, EGLSurface draw, EGLSurface read, EGLContext ctx) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *context = _eglLookupContext(ctx, disp); _EGLSurface *draw_surf = _eglLookupSurface(draw, disp); _EGLSurface *read_surf = _eglLookupSurface(read, disp); _EGLDriver *drv; + EGLBoolean ret; if (!disp) - return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); drv = disp->Driver; /* display is allowed to be uninitialized under certain condition */ if (!disp->Initialized) { if (draw != EGL_NO_SURFACE || read != EGL_NO_SURFACE || ctx != EGL_NO_CONTEXT) - return _eglError(EGL_BAD_DISPLAY, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_DISPLAY, EGL_FALSE); } if (!drv) - return EGL_TRUE; + return _EGL_SUCCESS(disp, EGL_TRUE); if (!context && ctx != EGL_NO_CONTEXT) - return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); if ((!draw_surf && draw != EGL_NO_SURFACE) || (!read_surf && read != EGL_NO_SURFACE)) - return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - return drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); + ret = drv->API.MakeCurrent(drv, disp, draw_surf, read_surf, context); + + return _EGL_EVAL(disp, ret); } @@ -422,8 +456,15 @@ EGLBoolean EGLAPIENTRY eglQueryContext(EGLDisplay dpy, EGLContext ctx, EGLint attribute, EGLint *value) { - _EGL_DECLARE_DD_AND_CONTEXT(dpy, ctx); - return drv->API.QueryContext(drv, disp, context, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLContext *context = _eglLookupContext(ctx, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_CONTEXT(disp, context, EGL_FALSE); + ret = drv->API.QueryContext(drv, disp, context, attribute, value); + + return _EGL_EVAL(disp, ret); } @@ -431,20 +472,18 @@ EGLSurface EGLAPIENTRY eglCreateWindowSurface(EGLDisplay dpy, EGLConfig config, EGLNativeWindowType window, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); surf = drv->API.CreateWindowSurface(drv, disp, conf, window, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + return _EGL_EVAL(disp, ret); } @@ -452,20 +491,18 @@ EGLSurface EGLAPIENTRY eglCreatePixmapSurface(EGLDisplay dpy, EGLConfig config, EGLNativePixmapType pixmap, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); surf = drv->API.CreatePixmapSurface(drv, disp, conf, pixmap, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + return _EGL_EVAL(disp, ret); } @@ -473,79 +510,118 @@ EGLSurface EGLAPIENTRY eglCreatePbufferSurface(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); surf = drv->API.CreatePbufferSurface(drv, disp, conf, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + return _EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglDestroySurface(EGLDisplay dpy, EGLSurface surface) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); _eglUnlinkSurface(surf); - return drv->API.DestroySurface(drv, disp, surf); + ret = drv->API.DestroySurface(drv, disp, surf); + + return _EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglQuerySurface(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint *value) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.QuerySurface(drv, disp, surf, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); + ret = drv->API.QuerySurface(drv, disp, surf, attribute, value); + + return _EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglSurfaceAttrib(EGLDisplay dpy, EGLSurface surface, EGLint attribute, EGLint value) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); + ret = drv->API.SurfaceAttrib(drv, disp, surf, attribute, value); + + return _EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglBindTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.BindTexImage(drv, disp, surf, buffer); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); + ret = drv->API.BindTexImage(drv, disp, surf, buffer); + + return _EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglReleaseTexImage(EGLDisplay dpy, EGLSurface surface, EGLint buffer) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.ReleaseTexImage(drv, disp, surf, buffer); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); + ret = drv->API.ReleaseTexImage(drv, disp, surf, buffer); + + return _EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglSwapInterval(EGLDisplay dpy, EGLint interval) { + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *ctx = _eglGetCurrentContext(); _EGLSurface *surf; - _EGL_DECLARE_DD(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE); if (!ctx || !_eglIsContextLinked(ctx) || ctx->Resource.Display != disp) - return _eglError(EGL_BAD_CONTEXT, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); surf = ctx->DrawSurface; if (!_eglIsSurfaceLinked(surf)) - return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - return drv->API.SwapInterval(drv, disp, surf, interval); + ret = drv->API.SwapInterval(drv, disp, surf, interval); + + return _EGL_EVAL(disp, ret); } @@ -553,21 +629,35 @@ EGLBoolean EGLAPIENTRY eglSwapBuffers(EGLDisplay dpy, EGLSurface surface) { _EGLContext *ctx = _eglGetCurrentContext(); - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); /* surface must be bound to current context in EGL 1.4 */ if (!ctx || !_eglIsContextLinked(ctx) || surf != ctx->DrawSurface) - return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); - return drv->API.SwapBuffers(drv, disp, surf); + ret = drv->API.SwapBuffers(drv, disp, surf); + + return _EGL_EVAL(disp, ret); } EGLBoolean EGLAPIENTRY eglCopyBuffers(EGLDisplay dpy, EGLSurface surface, EGLNativePixmapType target) { - _EGL_DECLARE_DD_AND_SURFACE(dpy, surface); - return drv->API.CopyBuffers(drv, disp, surf, target); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLSurface *surf = _eglLookupSurface(surface, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SURFACE(disp, surf, EGL_FALSE); + ret = drv->API.CopyBuffers(drv, disp, surf, target); + + return _EGL_EVAL(disp, ret); } @@ -577,19 +667,24 @@ eglWaitClient(void) _EGLContext *ctx = _eglGetCurrentContext(); _EGLDisplay *disp; _EGLDriver *drv; + EGLBoolean ret; if (!ctx) - return EGL_TRUE; + return _EGL_SUCCESS(NULL, EGL_TRUE); + + disp = ctx->Resource.Display; + _eglLockMutex(&disp->Mutex); + /* let bad current context imply bad current surface */ if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) - return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); /* a valid current context implies an initialized current display */ - disp = ctx->Resource.Display; assert(disp->Initialized); drv = disp->Driver; + ret = drv->API.WaitClient(drv, disp, ctx); - return drv->API.WaitClient(drv, disp, ctx); + return _EGL_EVAL(disp, ret); } @@ -603,7 +698,7 @@ eglWaitGL(void) EGLBoolean ret; if (api_index != es_index && _eglIsCurrentThreadDummy()) - return _eglError(EGL_BAD_ALLOC, "eglWaitGL"); + return _EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); t->CurrentAPIIndex = es_index; ret = eglWaitClient(); @@ -621,19 +716,24 @@ eglWaitNative(EGLint engine) _EGLContext *ctx = _eglGetCurrentContext(); _EGLDisplay *disp; _EGLDriver *drv; + EGLBoolean ret; if (!ctx) - return EGL_TRUE; + return _EGL_SUCCESS(NULL, EGL_TRUE); + + disp = ctx->Resource.Display; + _eglLockMutex(&disp->Mutex); + /* let bad current context imply bad current surface */ if (!_eglIsContextLinked(ctx) || !_eglIsSurfaceLinked(ctx->DrawSurface)) - return _eglError(EGL_BAD_CURRENT_SURFACE, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_CURRENT_SURFACE, EGL_FALSE); /* a valid current context implies an initialized current display */ - disp = ctx->Resource.Display; assert(disp->Initialized); drv = disp->Driver; + ret = drv->API.WaitNative(drv, disp, engine); - return drv->API.WaitNative(drv, disp, engine); + return _EGL_EVAL(disp, ret); } @@ -641,7 +741,11 @@ EGLDisplay EGLAPIENTRY eglGetCurrentDisplay(void) { _EGLContext *ctx = _eglGetCurrentContext(); - return (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; + EGLDisplay ret; + + ret = (ctx) ? _eglGetDisplayHandle(ctx->Resource.Display) : EGL_NO_DISPLAY; + + return _EGL_SUCCESS(NULL, ret); } @@ -649,7 +753,11 @@ EGLContext EGLAPIENTRY eglGetCurrentContext(void) { _EGLContext *ctx = _eglGetCurrentContext(); - return _eglGetContextHandle(ctx); + EGLContext ret; + + ret = _eglGetContextHandle(ctx); + + return _EGL_SUCCESS(NULL, ret); } @@ -657,10 +765,12 @@ EGLSurface EGLAPIENTRY eglGetCurrentSurface(EGLint readdraw) { _EGLContext *ctx = _eglGetCurrentContext(); + EGLint err = EGL_SUCCESS; _EGLSurface *surf; + EGLSurface ret; if (!ctx) - return EGL_NO_SURFACE; + return _EGL_SUCCESS(NULL, EGL_NO_SURFACE); switch (readdraw) { case EGL_DRAW: @@ -670,12 +780,14 @@ eglGetCurrentSurface(EGLint readdraw) surf = ctx->ReadSurface; break; default: - _eglError(EGL_BAD_PARAMETER, __FUNCTION__); surf = NULL; + err = EGL_BAD_PARAMETER; break; } - return _eglGetSurfaceHandle(surf); + ret = _eglGetSurfaceHandle(surf); + + return _EGL_ERROR(NULL, err, ret); } @@ -719,27 +831,34 @@ eglGetProcAddress(const char *procname) { NULL, NULL } }; EGLint i; + _EGLProc ret; if (!procname) - return NULL; + return _EGL_SUCCESS(NULL, NULL); + + ret = NULL; if (strncmp(procname, "egl", 3) == 0) { for (i = 0; egl_functions[i].name; i++) { - if (strcmp(egl_functions[i].name, procname) == 0) - return egl_functions[i].function; + if (strcmp(egl_functions[i].name, procname) == 0) { + ret = egl_functions[i].function; + break; + } } } + if (ret) + return _EGL_SUCCESS(NULL, ret); _eglPreloadDrivers(); /* now loop over drivers to query their procs */ for (i = 0; i < _eglGlobal.NumDrivers; i++) { _EGLDriver *drv = _eglGlobal.Drivers[i]; - _EGLProc p = drv->API.GetProcAddress(drv, procname); - if (p) - return p; + ret = drv->API.GetProcAddress(drv, procname); + if (ret) + break; } - return NULL; + return _EGL_SUCCESS(NULL, ret); } @@ -755,9 +874,16 @@ eglChooseModeMESA(EGLDisplay dpy, EGLScreenMESA screen, const EGLint *attrib_list, EGLModeMESA *modes, EGLint modes_size, EGLint *num_modes) { - _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); - return drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, - modes, modes_size, num_modes); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen(screen, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE); + ret = drv->API.ChooseModeMESA(drv, disp, scrn, attrib_list, + modes, modes_size, num_modes); + + return _EGL_EVAL(disp, ret); } @@ -765,8 +891,15 @@ EGLBoolean EGLAPIENTRY eglGetModesMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *modes, EGLint mode_size, EGLint *num_mode) { - _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); - return drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen(screen, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE); + ret = drv->API.GetModesMESA(drv, disp, scrn, modes, mode_size, num_mode); + + return _EGL_EVAL(disp, ret); } @@ -774,8 +907,15 @@ EGLBoolean EGLAPIENTRY eglGetModeAttribMESA(EGLDisplay dpy, EGLModeMESA mode, EGLint attribute, EGLint *value) { - _EGL_DECLARE_DD_AND_MODE(dpy, mode); - return drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLMode *m = _eglLookupMode(mode, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_MODE(disp, m, EGL_FALSE); + ret = drv->API.GetModeAttribMESA(drv, disp, m, attribute, value); + + return _EGL_EVAL(disp, ret); } @@ -783,20 +923,20 @@ EGLBoolean EGLAPIENTRY eglCopyContextMESA(EGLDisplay dpy, EGLContext source, EGLContext dest, EGLint mask) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *source_context = _eglLookupContext(source, disp); _EGLContext *dest_context = _eglLookupContext(dest, disp); _EGLDriver *drv; + EGLBoolean ret; - drv = _eglCheckContext(disp, source_context, __FUNCTION__); - if (!drv || !dest_context) { - if (drv) - _eglError(EGL_BAD_CONTEXT, __FUNCTION__); - return EGL_FALSE; - } + drv = _EGL_CHECK_CONTEXT(disp, source_context, EGL_FALSE); + if (!dest_context) + return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_FALSE); - return drv->API.CopyContextMESA(drv, disp, source_context, dest_context, - mask); + ret = drv->API.CopyContextMESA(drv, disp, + source_context, dest_context, mask); + + return _EGL_EVAL(disp, ret); } @@ -804,9 +944,14 @@ EGLBoolean eglGetScreensMESA(EGLDisplay dpy, EGLScreenMESA *screens, EGLint max_screens, EGLint *num_screens) { - _EGL_DECLARE_DD(dpy); - return drv->API.GetScreensMESA(drv, disp, screens, - max_screens, num_screens); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE); + ret = drv->API.GetScreensMESA(drv, disp, screens, max_screens, num_screens); + + return _EGL_EVAL(disp, ret); } @@ -814,20 +959,18 @@ EGLSurface eglCreateScreenSurfaceMESA(EGLDisplay dpy, EGLConfig config, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); surf = drv->API.CreateScreenSurfaceMESA(drv, disp, conf, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + return _EGL_EVAL(disp, ret); } @@ -835,29 +978,37 @@ EGLBoolean eglShowScreenSurfaceMESA(EGLDisplay dpy, EGLint screen, EGLSurface surface, EGLModeMESA mode) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); _EGLSurface *surf = _eglLookupSurface(surface, disp); _EGLMode *m = _eglLookupMode(mode, disp); _EGLDriver *drv; + EGLBoolean ret; - drv = _eglCheckScreen(disp, scrn, __FUNCTION__); - if (!drv) - return EGL_FALSE; + drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE); if (!surf && surface != EGL_NO_SURFACE) - return _eglError(EGL_BAD_SURFACE, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_SURFACE, EGL_FALSE); if (!m && mode != EGL_NO_MODE_MESA) - return _eglError(EGL_BAD_MODE_MESA, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_MODE_MESA, EGL_FALSE); - return drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); + ret = drv->API.ShowScreenSurfaceMESA(drv, disp, scrn, surf, m); + + return _EGL_EVAL(disp, ret); } EGLBoolean eglScreenPositionMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint x, EGLint y) { - _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); - return drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen(screen, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE); + ret = drv->API.ScreenPositionMESA(drv, disp, scrn, x, y); + + return _EGL_EVAL(disp, ret); } @@ -865,8 +1016,15 @@ EGLBoolean eglQueryScreenMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLint attribute, EGLint *value) { - _EGL_DECLARE_DD_AND_SCREEN(dpy, screen); - return drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLScreen *scrn = _eglLookupScreen(screen, disp); + _EGLDriver *drv; + EGLBoolean ret; + + drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE); + ret = drv->API.QueryScreenMESA(drv, disp, scrn, attribute, value); + + return _EGL_EVAL(disp, ret); } @@ -874,49 +1032,51 @@ EGLBoolean eglQueryScreenSurfaceMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLSurface *surface) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLBoolean ret; - drv = _eglCheckScreen(disp, scrn, __FUNCTION__); - if (!drv) - return EGL_FALSE; - - if (drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf) != EGL_TRUE) - surf = NULL; - if (surface) + drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE); + ret = drv->API.QueryScreenSurfaceMESA(drv, disp, scrn, &surf); + if (ret && surface) *surface = _eglGetSurfaceHandle(surf); - return (surf != NULL); + + return _EGL_EVAL(disp, ret); } EGLBoolean eglQueryScreenModeMESA(EGLDisplay dpy, EGLScreenMESA screen, EGLModeMESA *mode) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLScreen *scrn = _eglLookupScreen((EGLScreenMESA) screen, disp); _EGLDriver *drv; _EGLMode *m; + EGLBoolean ret; - drv = _eglCheckScreen(disp, scrn, __FUNCTION__); - if (!drv) - return EGL_FALSE; - - if (drv->API.QueryScreenModeMESA(drv, disp, scrn, &m) != EGL_TRUE) - m = NULL; - if (mode) + drv = _EGL_CHECK_SCREEN(disp, scrn, EGL_FALSE); + ret = drv->API.QueryScreenModeMESA(drv, disp, scrn, &m); + if (ret && mode) *mode = m->Handle; - return (m != NULL); + return _EGL_EVAL(disp, ret); } const char * eglQueryModeStringMESA(EGLDisplay dpy, EGLModeMESA mode) { - _EGL_DECLARE_DD_AND_MODE(dpy, mode); - return drv->API.QueryModeStringMESA(drv, disp, m); + _EGLDisplay *disp = _eglLockDisplay(dpy); + _EGLMode *m = _eglLookupMode(mode, disp); + _EGLDriver *drv; + const char *ret; + + drv = _EGL_CHECK_MODE(disp, m, NULL); + ret = drv->API.QueryModeStringMESA(drv, disp, m); + + return _EGL_EVAL(disp, ret); } @@ -947,13 +1107,14 @@ eglBindAPI(EGLenum api) _EGLThreadInfo *t = _eglGetCurrentThread(); if (_eglIsCurrentThreadDummy()) - return _eglError(EGL_BAD_ALLOC, "eglBindAPI"); + return _EGL_ERROR(NULL, EGL_BAD_ALLOC, EGL_FALSE); if (!_eglIsApiValid(api)) - return _eglError(EGL_BAD_PARAMETER, "eglBindAPI"); + return _EGL_ERROR(NULL, EGL_BAD_PARAMETER, EGL_FALSE); t->CurrentAPIIndex = _eglConvertApiToIndex(api); - return EGL_TRUE; + + return _EGL_SUCCESS(NULL, EGL_TRUE); } @@ -963,9 +1124,13 @@ eglBindAPI(EGLenum api) EGLenum eglQueryAPI(void) { - /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ _EGLThreadInfo *t = _eglGetCurrentThread(); - return _eglConvertApiFromIndex(t->CurrentAPIIndex); + EGLenum ret; + + /* returns one of EGL_OPENGL_API, EGL_OPENGL_ES_API or EGL_OPENVG_API */ + ret = _eglConvertApiFromIndex(t->CurrentAPIIndex); + + return _EGL_SUCCESS(NULL, ret); } @@ -974,21 +1139,19 @@ eglCreatePbufferFromClientBuffer(EGLDisplay dpy, EGLenum buftype, EGLClientBuffer buffer, EGLConfig config, const EGLint *attrib_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLConfig *conf = _eglLookupConfig(config, disp); _EGLDriver *drv; _EGLSurface *surf; + EGLSurface ret; - drv = _eglCheckConfig(disp, conf, __FUNCTION__); - if (!drv) - return EGL_NO_SURFACE; + drv = _EGL_CHECK_CONFIG(disp, conf, EGL_NO_SURFACE); surf = drv->API.CreatePbufferFromClientBuffer(drv, disp, buftype, buffer, conf, attrib_list); - if (surf) - return _eglLinkSurface(surf, disp); - else - return EGL_NO_SURFACE; + ret = (surf) ? _eglLinkSurface(surf, disp) : EGL_NO_SURFACE; + + return _EGL_EVAL(disp, ret); } @@ -1005,9 +1168,14 @@ eglReleaseThread(void) _EGLContext *ctx = t->CurrentContexts[i]; if (ctx) { _EGLDisplay *disp = ctx->Resource.Display; - _EGLDriver *drv = disp->Driver; + _EGLDriver *drv; + t->CurrentAPIIndex = i; + + _eglLockMutex(&disp->Mutex); + drv = disp->Driver; (void) drv->API.MakeCurrent(drv, disp, NULL, NULL, NULL); + _eglUnlockMutex(&disp->Mutex); } } @@ -1015,7 +1183,8 @@ eglReleaseThread(void) } _eglDestroyCurrentThread(); - return EGL_TRUE; + + return _EGL_SUCCESS(NULL, EGL_TRUE); } @@ -1029,42 +1198,40 @@ EGLImageKHR eglCreateImageKHR(EGLDisplay dpy, EGLContext ctx, EGLenum target, EGLClientBuffer buffer, const EGLint *attr_list) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLContext *context = _eglLookupContext(ctx, disp); _EGLDriver *drv; _EGLImage *img; + EGLImageKHR ret; - drv = _eglCheckDisplay(disp, __FUNCTION__); - if (!drv) - return EGL_NO_IMAGE_KHR; - if (!context && ctx != EGL_NO_CONTEXT) { - _eglError(EGL_BAD_CONTEXT, __FUNCTION__); - return EGL_NO_IMAGE_KHR; - } + drv = _EGL_CHECK_DISPLAY(disp, EGL_NO_IMAGE_KHR); + if (!context && ctx != EGL_NO_CONTEXT) + return _EGL_ERROR(disp, EGL_BAD_CONTEXT, EGL_NO_IMAGE_KHR); img = drv->API.CreateImageKHR(drv, disp, context, target, buffer, attr_list); - if (img) - return _eglLinkImage(img, disp); - else - return EGL_NO_IMAGE_KHR; + ret = (img) ? _eglLinkImage(img, disp) : EGL_NO_IMAGE_KHR; + + return _EGL_EVAL(disp, ret); } -EGLBoolean eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) +EGLBoolean +eglDestroyImageKHR(EGLDisplay dpy, EGLImageKHR image) { - _EGLDisplay *disp = _eglLookupDisplay(dpy); + _EGLDisplay *disp = _eglLockDisplay(dpy); _EGLImage *img = _eglLookupImage(image, disp); _EGLDriver *drv; + EGLBoolean ret; - drv = _eglCheckDisplay(disp, __FUNCTION__); - if (!drv) - return EGL_FALSE; + drv = _EGL_CHECK_DISPLAY(disp, EGL_FALSE); if (!img) - return _eglError(EGL_BAD_PARAMETER, __FUNCTION__); + return _EGL_ERROR(disp, EGL_BAD_PARAMETER, EGL_FALSE); _eglUnlinkImage(img); - return drv->API.DestroyImageKHR(drv, disp, img); + ret = drv->API.DestroyImageKHR(drv, disp, img); + + return _EGL_EVAL(disp, ret); } diff --git a/src/egl/main/eglapi.h b/src/egl/main/eglapi.h index c3676ec56a..3e2ba8dd41 100644 --- a/src/egl/main/eglapi.h +++ b/src/egl/main/eglapi.h @@ -45,6 +45,7 @@ typedef const char *(*QueryString_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint n typedef EGLBoolean (*WaitClient_t)(_EGLDriver *drv, _EGLDisplay *dpy, _EGLContext *ctx); typedef EGLBoolean (*WaitNative_t)(_EGLDriver *drv, _EGLDisplay *dpy, EGLint engine); +/* this function may be called from multiple threads at the same time */ typedef _EGLProc (*GetProcAddress_t)(_EGLDriver *drv, const char *procname); diff --git a/src/egl/main/eglcurrent.c b/src/egl/main/eglcurrent.c index 989c19a2fa..c697bf796d 100644 --- a/src/egl/main/eglcurrent.c +++ b/src/egl/main/eglcurrent.c @@ -248,19 +248,20 @@ _eglGetCurrentContext(void) /** - * Record EGL error code. + * Record EGL error code and return EGL_FALSE. */ EGLBoolean _eglError(EGLint errCode, const char *msg) { _EGLThreadInfo *t = _eglGetCurrentThread(); - const char *s; if (t == &dummy_thread) return EGL_FALSE; - if (t->LastError == EGL_SUCCESS) { - t->LastError = errCode; + t->LastError = errCode; + + if (errCode != EGL_SUCCESS) { + const char *s; switch (errCode) { case EGL_BAD_ACCESS: diff --git a/src/egl/main/egldisplay.c b/src/egl/main/egldisplay.c index d7a8d14292..f7dbe8ec22 100644 --- a/src/egl/main/egldisplay.c +++ b/src/egl/main/egldisplay.c @@ -45,72 +45,8 @@ _eglFiniDisplay(void) /** - * Allocate a new _EGLDisplay object for the given nativeDisplay handle. - * We'll also try to determine the device driver name at this time. - * - * Note that nativeDisplay may be an X Display ptr, or a string. - */ -_EGLDisplay * -_eglNewDisplay(EGLNativeDisplayType nativeDisplay) -{ - _EGLDisplay *dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay)); - if (dpy) { - dpy->NativeDisplay = nativeDisplay; - } - return dpy; -} - - -/** - * Link a display to itself and return the handle of the link. - * The handle can be passed to client directly. - */ -EGLDisplay -_eglLinkDisplay(_EGLDisplay *dpy) -{ - _eglLockMutex(_eglGlobal.Mutex); - - dpy->Next = _eglGlobal.DisplayList; - _eglGlobal.DisplayList = dpy; - - _eglUnlockMutex(_eglGlobal.Mutex); - - return (EGLDisplay) dpy; -} - - -/** - * Unlink a linked display from itself. - * Accessing an unlinked display should generate EGL_BAD_DISPLAY error. - */ -void -_eglUnlinkDisplay(_EGLDisplay *dpy) -{ - _EGLDisplay *prev; - - _eglLockMutex(_eglGlobal.Mutex); - - prev = _eglGlobal.DisplayList; - if (prev != dpy) { - while (prev) { - if (prev->Next == dpy) - break; - prev = prev->Next; - } - assert(prev); - prev->Next = dpy->Next; - } - else { - _eglGlobal.DisplayList = dpy->Next; - } - - _eglUnlockMutex(_eglGlobal.Mutex); -} - - -/** - * Find the display corresponding to the specified native display id in all - * linked displays. + * Find the display corresponding to the specified native display, or create a + * new one. */ _EGLDisplay * _eglFindDisplay(EGLNativeDisplayType nativeDisplay) @@ -119,18 +55,30 @@ _eglFindDisplay(EGLNativeDisplayType nativeDisplay) _eglLockMutex(_eglGlobal.Mutex); + /* search the display list first */ dpy = _eglGlobal.DisplayList; while (dpy) { - if (dpy->NativeDisplay == nativeDisplay) { - _eglUnlockMutex(_eglGlobal.Mutex); - return dpy; - } + if (dpy->NativeDisplay == nativeDisplay) + break; dpy = dpy->Next; } + /* create a new display */ + if (!dpy) { + dpy = (_EGLDisplay *) calloc(1, sizeof(_EGLDisplay)); + if (dpy) { + _eglInitMutex(&dpy->Mutex); + dpy->NativeDisplay = nativeDisplay; + + /* add to the display list */ + dpy->Next = _eglGlobal.DisplayList; + _eglGlobal.DisplayList = dpy; + } + } + _eglUnlockMutex(_eglGlobal.Mutex); - return NULL; + return dpy; } diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h index 03903290fd..43b39bda9d 100644 --- a/src/egl/main/egldisplay.h +++ b/src/egl/main/egldisplay.h @@ -4,6 +4,7 @@ #include "egltypedefs.h" #include "egldefines.h" +#include "eglmutex.h" enum _egl_resource_type { @@ -53,6 +54,8 @@ struct _egl_display /* used to link displays */ _EGLDisplay *Next; + _EGLMutex Mutex; + EGLNativeDisplayType NativeDisplay; EGLBoolean Initialized; /**< True if the display is initialized */ @@ -85,19 +88,7 @@ _eglFiniDisplay(void); extern _EGLDisplay * -_eglNewDisplay(EGLNativeDisplayType displayName); - - -extern EGLDisplay -_eglLinkDisplay(_EGLDisplay *dpy); - - -extern void -_eglUnlinkDisplay(_EGLDisplay *dpy); - - -extern _EGLDisplay * -_eglFindDisplay(EGLNativeDisplayType nativeDisplay); +_eglFindDisplay(EGLNativeDisplayType displayName); PUBLIC void @@ -164,16 +155,6 @@ _eglGetDisplayHandle(_EGLDisplay *dpy) } -/** - * Return true if the display is linked. - */ -static INLINE EGLBoolean -_eglIsDisplayLinked(_EGLDisplay *dpy) -{ - return (EGLBoolean) (_eglGetDisplayHandle(dpy) != EGL_NO_DISPLAY); -} - - extern void _eglLinkResource(_EGLResource *res, _EGLResourceType type, _EGLDisplay *dpy); diff --git a/src/egl/main/egldriver.c b/src/egl/main/egldriver.c index a87c697b11..8748fe5f46 100644 --- a/src/egl/main/egldriver.c +++ b/src/egl/main/egldriver.c @@ -237,6 +237,10 @@ _eglMatchDriver(_EGLDisplay *dpy) _EGLDriver *best_drv = NULL; EGLint best_score = -1, i; + /* + * this function is called after preloading and the drivers never change + * after preloading. + */ for (i = 0; i < _eglGlobal.NumDrivers; i++) { _EGLDriver *drv = _eglGlobal.Drivers[i]; EGLint score; @@ -529,14 +533,21 @@ _eglPreloadDrivers(void) { EGLBoolean loaded; + /* protect the preloading process */ + _eglLockMutex(_eglGlobal.Mutex); + /* already preloaded */ - if (_eglGlobal.NumDrivers) + if (_eglGlobal.NumDrivers) { + _eglUnlockMutex(_eglGlobal.Mutex); return EGL_TRUE; + } loaded = (_eglPreloadUserDriver() || _eglPreloadDisplayDrivers() || _eglPreloadDefaultDriver()); + _eglUnlockMutex(_eglGlobal.Mutex); + return loaded; } @@ -548,6 +559,8 @@ void _eglUnloadDrivers(void) { EGLint i; + + /* this is called at atexit time */ for (i = 0; i < _eglGlobal.NumDrivers; i++) { _EGLDriver *drv = _eglGlobal.Drivers[i]; lib_handle handle = drv->LibHandle; diff --git a/src/egl/main/eglglobals.h b/src/egl/main/eglglobals.h index cd1dd5851b..4368898020 100644 --- a/src/egl/main/eglglobals.h +++ b/src/egl/main/eglglobals.h @@ -18,6 +18,7 @@ struct _egl_global EGLScreenMESA FreeScreenHandle; + /* these never change after preloading */ EGLint NumDrivers; _EGLDriver *Drivers[10]; diff --git a/src/egl/main/eglscreen.c b/src/egl/main/eglscreen.c index 97a405a4b4..c47afd6abd 100644 --- a/src/egl/main/eglscreen.c +++ b/src/egl/main/eglscreen.c @@ -22,17 +22,22 @@ #include "eglconfig.h" #include "eglsurface.h" #include "eglscreen.h" +#include "eglmutex.h" /** * Return a new screen handle/ID. * NOTE: we never reuse these! */ -EGLScreenMESA +static EGLScreenMESA _eglAllocScreenHandle(void) { - EGLScreenMESA s = _eglGlobal.FreeScreenHandle; - _eglGlobal.FreeScreenHandle++; + EGLScreenMESA s; + + _eglLockMutex(_eglGlobal.Mutex); + s = _eglGlobal.FreeScreenHandle++; + _eglUnlockMutex(_eglGlobal.Mutex); + return s; } diff --git a/src/egl/main/eglscreen.h b/src/egl/main/eglscreen.h index c400ac3d15..0fd71f71fc 100644 --- a/src/egl/main/eglscreen.h +++ b/src/egl/main/eglscreen.h @@ -29,10 +29,6 @@ struct _egl_screen }; -extern EGLScreenMESA -_eglAllocScreenHandle(void); - - PUBLIC void _eglInitScreen(_EGLScreen *screen); diff --git a/src/gallium/auxiliary/Makefile b/src/gallium/auxiliary/Makefile index 507ca6e6aa..ff7695150e 100644 --- a/src/gallium/auxiliary/Makefile +++ b/src/gallium/auxiliary/Makefile @@ -49,8 +49,10 @@ C_SOURCES = \ indices/u_indices_gen.c \ indices/u_unfilled_gen.c \ os/os_misc.c \ + os/os_stream_log.c \ os/os_stream_stdc.c \ - os/os_stream_wd.c \ + os/os_stream_str.c \ + os/os_stream_null.c \ os/os_time.c \ pipebuffer/pb_buffer_malloc.c \ pipebuffer/pb_bufmgr_alt.c \ @@ -91,9 +93,10 @@ C_SOURCES = \ translate/translate.c \ translate/translate_cache.c \ util/u_debug.c \ - util/u_debug_dump.c \ util/u_debug_symbol.c \ util/u_debug_stack.c \ + util/u_dump_defines.c \ + util/u_dump_state.c \ util/u_bitmask.c \ util/u_blit.c \ util/u_blitter.c \ diff --git a/src/gallium/auxiliary/SConscript b/src/gallium/auxiliary/SConscript index 9709344b54..b531ad2dbd 100644 --- a/src/gallium/auxiliary/SConscript +++ b/src/gallium/auxiliary/SConscript @@ -83,8 +83,10 @@ source = [ 'indices/u_indices_gen.c', 'indices/u_unfilled_gen.c', 'os/os_misc.c', + 'os/os_stream_log.c', 'os/os_stream_stdc.c', - 'os/os_stream_wd.c', + 'os/os_stream_str.c', + 'os/os_stream_null.c', 'os/os_time.c', 'pipebuffer/pb_buffer_fenced.c', 'pipebuffer/pb_buffer_malloc.c', @@ -131,10 +133,11 @@ source = [ 'util/u_cache.c', 'util/u_cpu_detect.c', 'util/u_debug.c', - 'util/u_debug_dump.c', 'util/u_debug_memory.c', 'util/u_debug_stack.c', 'util/u_debug_symbol.c', + 'util/u_dump_defines.c', + 'util/u_dump_state.c', 'util/u_dl.c', 'util/u_draw_quad.c', 'util/u_format.c', diff --git a/src/gallium/auxiliary/cso_cache/cso_context.c b/src/gallium/auxiliary/cso_cache/cso_context.c index c638239e80..b5241fa64c 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.c +++ b/src/gallium/auxiliary/cso_cache/cso_context.c @@ -93,6 +93,7 @@ struct cso_context { struct pipe_framebuffer_state fb, fb_saved; struct pipe_viewport_state vp, vp_saved; struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref, stencil_ref_saved; }; @@ -1057,8 +1058,6 @@ void cso_restore_viewport(struct cso_context *ctx) } - - enum pipe_error cso_set_blend_color(struct cso_context *ctx, const struct pipe_blend_color *bc) { @@ -1069,6 +1068,30 @@ enum pipe_error cso_set_blend_color(struct cso_context *ctx, return PIPE_OK; } +enum pipe_error cso_set_stencil_ref(struct cso_context *ctx, + const struct pipe_stencil_ref *sr) +{ + if (memcmp(&ctx->stencil_ref, sr, sizeof(ctx->stencil_ref))) { + ctx->stencil_ref = *sr; + ctx->pipe->set_stencil_ref(ctx->pipe, sr); + } + return PIPE_OK; +} + +void cso_save_stencil_ref(struct cso_context *ctx) +{ + ctx->stencil_ref_saved = ctx->stencil_ref; +} + + +void cso_restore_stencil_ref(struct cso_context *ctx) +{ + if (memcmp(&ctx->stencil_ref, &ctx->stencil_ref_saved, sizeof(ctx->stencil_ref))) { + ctx->stencil_ref = ctx->stencil_ref_saved; + ctx->pipe->set_stencil_ref(ctx->pipe, &ctx->stencil_ref); + } +} + enum pipe_error cso_set_geometry_shader_handle(struct cso_context *ctx, void *handle) { diff --git a/src/gallium/auxiliary/cso_cache/cso_context.h b/src/gallium/auxiliary/cso_cache/cso_context.h index d2089b1c88..707b3c2cee 100644 --- a/src/gallium/auxiliary/cso_cache/cso_context.h +++ b/src/gallium/auxiliary/cso_cache/cso_context.h @@ -174,6 +174,12 @@ enum pipe_error cso_set_blend_color(struct cso_context *cso, const struct pipe_blend_color *bc); +enum pipe_error cso_set_stencil_ref(struct cso_context *cso, + const struct pipe_stencil_ref *sr); +void cso_save_stencil_ref(struct cso_context *cso); +void cso_restore_stencil_ref(struct cso_context *cso); + + #ifdef __cplusplus } #endif diff --git a/src/gallium/auxiliary/draw/draw_pt.c b/src/gallium/auxiliary/draw/draw_pt.c index f5ed32d0b0..341353f628 100644 --- a/src/gallium/auxiliary/draw/draw_pt.c +++ b/src/gallium/auxiliary/draw/draw_pt.c @@ -310,7 +310,7 @@ draw_arrays_instanced(struct draw_context *draw, debug_printf("Elements:\n"); for (i = 0; i < draw->pt.nr_vertex_elements; i++) { debug_printf(" format=%s comps=%u\n", - pf_name(draw->pt.vertex_element[i].src_format), + util_format_name(draw->pt.vertex_element[i].src_format), draw->pt.vertex_element[i].nr_components); } debug_printf("Buffers:\n"); diff --git a/src/gallium/auxiliary/draw/draw_vs.c b/src/gallium/auxiliary/draw/draw_vs.c index 6bdd612e6f..9085838022 100644 --- a/src/gallium/auxiliary/draw/draw_vs.c +++ b/src/gallium/auxiliary/draw/draw_vs.c @@ -61,6 +61,7 @@ draw_vs_set_constants(struct draw_context *draw, } draw->vs.aligned_constant_storage[slot] = align_malloc(size, 16); } + assert(constants); memcpy((void *)draw->vs.aligned_constant_storage[slot], constants, size); diff --git a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c index 57c2b763e4..e268862282 100644 --- a/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c +++ b/src/gallium/auxiliary/gallivm/lp_bld_sample_soa.c @@ -35,7 +35,7 @@ #include "pipe/p_defines.h" #include "pipe/p_state.h" #include "util/u_debug.h" -#include "util/u_debug_dump.h" +#include "util/u_dump.h" #include "util/u_memory.h" #include "util/u_math.h" #include "util/u_format.h" @@ -173,7 +173,7 @@ lp_build_sample_wrap(struct lp_build_sample_context *bld, case PIPE_TEX_WRAP_MIRROR_CLAMP_TO_BORDER: /* FIXME */ _debug_printf("llvmpipe: failed to translate texture wrap mode %s\n", - debug_dump_tex_wrap(wrap_mode, TRUE)); + util_dump_tex_wrap(wrap_mode, TRUE)); coord = lp_build_max(int_coord_bld, coord, int_coord_bld->zero); coord = lp_build_min(int_coord_bld, coord, length_minus_one); break; diff --git a/src/gallium/auxiliary/os/os_stream.h b/src/gallium/auxiliary/os/os_stream.h index bf30e6542d..693a0621e2 100644 --- a/src/gallium/auxiliary/os/os_stream.h +++ b/src/gallium/auxiliary/os/os_stream.h @@ -37,25 +37,86 @@ #include "pipe/p_compiler.h" -struct os_stream; - - /** - * Create a stream - * @param filename relative or absolute path (necessary for windows) - * @param optional maximum file size (0 for a growable size). + * OS stream (FILE, socket, etc) abstraction. */ +struct os_stream +{ + void + (*close)(struct os_stream *stream); + + boolean + (*write)(struct os_stream *stream, const void *data, size_t size); + + void + (*flush)(struct os_stream *stream); +}; + + +static INLINE void +os_stream_close(struct os_stream *stream) +{ + if (!stream) + return; + + stream->close(stream); +} + + +static INLINE boolean +os_stream_write(struct os_stream *stream, const void *data, size_t size) +{ + if (!stream) + return FALSE; + return stream->write(stream, data, size); +} + + +static INLINE boolean +os_stream_write_str(struct os_stream *stream, const char *str) +{ + size_t size; + if (!stream) + return FALSE; + for(size = 0; str[size]; ++size) + ; + return stream->write(stream, str, size); +} + + +static INLINE void +os_stream_flush(struct os_stream *stream) +{ + stream->flush(stream); +} + + +struct os_stream * +os_file_stream_create(const char *filename); + + +struct os_stream * +os_null_stream_create(void); + + +extern struct os_stream * +os_log_stream; + + struct os_stream * -os_stream_create(const char *filename, size_t max_size); +os_str_stream_create(size_t initial_size); + + +const char * +os_str_stream_get(struct os_stream *stream); -boolean -os_stream_write(struct os_stream *stream, const void *data, size_t size); +char * +os_str_stream_get_and_close(struct os_stream *stream); -void -os_stream_flush(struct os_stream *stream); -void -os_stream_close(struct os_stream *stream); +#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) +#define os_file_stream_create(_filename) os_null_stream_create() +#endif #endif /* _OS_STREAM_H_ */ diff --git a/src/gallium/auxiliary/util/u_debug_dump.h b/src/gallium/auxiliary/os/os_stream_log.c index 19b130ad18..7cc2028a22 100644 --- a/src/gallium/auxiliary/util/u_debug_dump.h +++ b/src/gallium/auxiliary/os/os_stream_log.c @@ -1,8 +1,8 @@ /************************************************************************** - * - * Copyright 2009 VMware, Inc. + * + * Copyright 2008-2010 VMware, Inc. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,11 +10,11 @@ * 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. @@ -22,56 +22,60 @@ * 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 - * Dump data in human/machine readable format. - * - * @author Jose Fonseca <jfonseca@vmware.com> + * Debug logging stream implementation. */ -#ifndef U_DEBUG_DUMP_H_ -#define U_DEBUG_DUMP_H_ +#include "os_memory.h" +#include "os_misc.h" +#include "os_stream.h" -#include "pipe/p_compiler.h" -#include "pipe/p_state.h" - - -#ifdef __cplusplus -extern "C" { -#endif +static void +os_log_stream_close(struct os_stream *stream) +{ + (void)stream; +} -const char * -debug_dump_blend_factor(unsigned value, boolean shortened); +static boolean +os_log_stream_write(struct os_stream *stream, const void *data, size_t size) +{ + char *str; -const char * -debug_dump_blend_func(unsigned value, boolean shortened); + str = os_malloc(size + 1); + if (!str) + return FALSE; -const char * -debug_dump_func(unsigned value, boolean shortened); + memcpy(str, data, size); + str[size] = 0; -const char * -debug_dump_tex_target(unsigned value, boolean shortened); + os_log_message(str); -const char * -debug_dump_tex_wrap(unsigned value, boolean shortened); + os_free(str); -const char * -debug_dump_tex_mipfilter(unsigned value, boolean shortened); + return TRUE; +} -const char * -debug_dump_tex_filter(unsigned value, boolean shortened); +static void +os_log_stream_flush(struct os_stream *stream) +{ + (void)stream; +} -/* FIXME: Move the other debug_dump_xxx functions out of u_debug.h into here. */ +static struct os_stream +os_log_stream_struct = { + &os_log_stream_close, + &os_log_stream_write, + &os_log_stream_flush +}; -#ifdef __cplusplus -} -#endif -#endif /* U_DEBUG_H_ */ +struct os_stream * +os_log_stream = &os_log_stream_struct; diff --git a/src/mesa/state_tracker/st_cb_viewport.c b/src/gallium/auxiliary/os/os_stream_null.c index b29191abef..128c4e8f0e 100644 --- a/src/mesa/state_tracker/st_cb_viewport.c +++ b/src/gallium/auxiliary/os/os_stream_null.c @@ -1,8 +1,8 @@ /************************************************************************** - * - * Copyright 2009 VMware, Inc. + * + * Copyright 2008-2010 VMware, Inc. * All Rights Reserved. - * + * * Permission is hereby granted, free of charge, to any person obtaining a * copy of this software and associated documentation files (the * "Software"), to deal in the Software without restriction, including @@ -10,41 +10,63 @@ * 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 TUNGSTEN GRAPHICS AND/OR ITS SUPPLIERS BE LIABLE FOR + * IN NO EVENT SHALL VMWARE AND/OR ITS 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. - * + * **************************************************************************/ -#include "main/glheader.h" -#include "st_context.h" -#include "st_cb_viewport.h" +/** + * @file + * Null stream implementation. + */ -#include "pipe/p_context.h" -#include "pipe/p_state.h" -#include "pipe/p_defines.h" +#include "os_memory.h" +#include "os_stream.h" -static void st_viewport(GLcontext * ctx, GLint x, GLint y, - GLsizei width, GLsizei height) +static void +os_null_stream_close(struct os_stream *stream) { - struct st_context *st = ctx->st; + (void)stream; +} + + +static boolean +os_null_stream_write(struct os_stream *stream, const void *data, size_t size) +{ + (void)data; + (void)size; + return TRUE; +} - if (st->pipe->screen && st->pipe->screen->update_buffer) - st->pipe->screen->update_buffer( st->pipe->screen, - st->pipe->priv ); + +static void +os_null_stream_flush(struct os_stream *stream) +{ + (void)stream; } -void st_init_viewport_functions(struct dd_function_table *functions) + +static struct os_stream +os_null_stream = { + &os_null_stream_close, + &os_null_stream_write, + &os_null_stream_flush +}; + + +struct os_stream * +os_null_stream_create() { - functions->Viewport = st_viewport; + return &os_null_stream; } diff --git a/src/gallium/auxiliary/os/os_stream_stdc.c b/src/gallium/auxiliary/os/os_stream_stdc.c index caa60c0b50..9e7ed71107 100644 --- a/src/gallium/auxiliary/os/os_stream_stdc.c +++ b/src/gallium/auxiliary/os/os_stream_stdc.c @@ -40,65 +40,73 @@ #include "os_stream.h" -struct os_stream +struct os_stdc_stream { + struct os_stream base; + FILE *file; }; -struct os_stream * -os_stream_create(const char *filename, size_t max_size) +static INLINE struct os_stdc_stream * +os_stdc_stream(struct os_stream *stream) { - struct os_stream *stream; - - (void)max_size; - - stream = (struct os_stream *)calloc(1, sizeof(struct os_stream)); - if(!stream) - goto no_stream; - - stream->file = fopen(filename, "w"); - if(!stream->file) - goto no_file; - - return stream; - -no_file: + return (struct os_stdc_stream *)stream; +} + + +static void +os_stdc_stream_close(struct os_stream *_stream) +{ + struct os_stdc_stream *stream = os_stdc_stream(_stream); + + fclose(stream->file); + free(stream); -no_stream: - return NULL; } -boolean -os_stream_write(struct os_stream *stream, const void *data, size_t size) +static boolean +os_stdc_stream_write(struct os_stream *_stream, const void *data, size_t size) { - if(!stream) - return FALSE; - + struct os_stdc_stream *stream = os_stdc_stream(_stream); + return fwrite(data, size, 1, stream->file) == size ? TRUE : FALSE; } -void -os_stream_flush(struct os_stream *stream) +static void +os_stdc_stream_flush(struct os_stream *_stream) { - if(!stream) - return; - + struct os_stdc_stream *stream = os_stdc_stream(_stream); + fflush(stream->file); } -void -os_stream_close(struct os_stream *stream) +struct os_stream * +os_file_stream_create(const char *filename) { + struct os_stdc_stream *stream; + + stream = (struct os_stdc_stream *)calloc(1, sizeof(*stream)); if(!stream) - return; - - fclose(stream->file); + goto no_stream; + + stream->base.close = &os_stdc_stream_close; + stream->base.write = &os_stdc_stream_write; + stream->base.flush = &os_stdc_stream_flush; + stream->file = fopen(filename, "w"); + if(!stream->file) + goto no_file; + + return &stream->base; + +no_file: free(stream); +no_stream: + return NULL; } diff --git a/src/gallium/auxiliary/os/os_stream_str.c b/src/gallium/auxiliary/os/os_stream_str.c new file mode 100644 index 0000000000..b5c7270d2a --- /dev/null +++ b/src/gallium/auxiliary/os/os_stream_str.c @@ -0,0 +1,166 @@ +/************************************************************************** + * + * Copyright 2008-2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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 VMWARE AND/OR ITS 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 + * Malloc string stream implementation. + */ + +#include "pipe/p_config.h" + +#include "os_memory.h" +#include "os_stream.h" + + +struct os_str_stream +{ + struct os_stream base; + + char *str; + + size_t size; + size_t written; +}; + + +static INLINE struct os_str_stream * +os_str_stream(struct os_stream *stream) +{ + return (struct os_str_stream *)stream; +} + + +static void +os_str_stream_close(struct os_stream *_stream) +{ + struct os_str_stream *stream = os_str_stream(_stream); + + os_free(stream->str); + + os_free(stream); +} + + +static boolean +os_str_stream_write(struct os_stream *_stream, const void *data, size_t size) +{ + struct os_str_stream *stream = os_str_stream(_stream); + size_t minimum_size; + boolean ret = TRUE; + + minimum_size = stream->written + size + 1; + if (stream->size < minimum_size) { + size_t new_size = stream->size; + char * new_str; + + do { + new_size *= 2; + } while (new_size < minimum_size); + + new_str = os_realloc(stream->str, stream->size, new_size); + if (new_str) { + stream->str = new_str; + stream->size = new_size; + } + else { + size = stream->size - stream->written - 1; + ret = FALSE; + } + } + + memcpy(stream->str + stream->written, data, size); + stream->written += size; + + return ret; +} + + +static void +os_str_stream_flush(struct os_stream *stream) +{ + (void)stream; +} + + +struct os_stream * +os_str_stream_create(size_t size) +{ + struct os_str_stream *stream; + + stream = (struct os_str_stream *)os_calloc(1, sizeof(*stream)); + if(!stream) + goto no_stream; + + stream->base.close = &os_str_stream_close; + stream->base.write = &os_str_stream_write; + stream->base.flush = &os_str_stream_flush; + + stream->str = os_malloc(size); + if(!stream->str) + goto no_str; + + stream->size = size; + + return &stream->base; + +no_str: + os_free(stream); +no_stream: + return NULL; +} + + +const char * +os_str_stream_get(struct os_stream *_stream) +{ + struct os_str_stream *stream = os_str_stream(_stream); + + if (!stream) + return NULL; + + stream->str[stream->written] = 0; + return stream->str; +} + + +char * +os_str_stream_get_and_close(struct os_stream *_stream) +{ + struct os_str_stream *stream = os_str_stream(_stream); + char *str; + + if (!stream) + return NULL; + + str = stream->str; + + str[stream->written] = 0; + + os_free(stream); + + return str; +} diff --git a/src/gallium/auxiliary/os/os_stream_wd.c b/src/gallium/auxiliary/os/os_stream_wd.c deleted file mode 100644 index a64cbcab4c..0000000000 --- a/src/gallium/auxiliary/os/os_stream_wd.c +++ /dev/null @@ -1,222 +0,0 @@ -/************************************************************************** - * - * Copyright 2008-2010 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, 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 VMWARE AND/OR ITS 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 - * Stream implementation for the Windows Display driver. - */ - -#include "pipe/p_config.h" - -#if defined(PIPE_SUBSYSTEM_WINDOWS_DISPLAY) - -#include <windows.h> -#include <winddi.h> - -#include "os_memory.h" -#include "os_stream.h" - - -#define MAP_FILE_SIZE (4*1024*1024) - - -struct os_stream -{ - char filename[MAX_PATH + 1]; - WCHAR wFileName[MAX_PATH + 1]; - boolean growable; - size_t map_size; - ULONG_PTR iFile; - char *pMap; - size_t written; - unsigned suffix; -}; - - -static INLINE boolean -os_stream_map(struct os_stream *stream) -{ - ULONG BytesInUnicodeString; - static char filename[MAX_PATH + 1]; - unsigned filename_len; - - if(stream->growable) - filename_len = snprintf(filename, - sizeof(filename), - "%s.%04x", - stream->filename, - stream->suffix++); - else - filename_len = snprintf(filename, - sizeof(filename), - "%s", - stream->filename); - - EngMultiByteToUnicodeN( - stream->wFileName, - sizeof(stream->wFileName), - &BytesInUnicodeString, - filename, - filename_len); - - stream->pMap = EngMapFile(stream->wFileName, stream->map_size, &stream->iFile); - if(!stream->pMap) - return FALSE; - - memset(stream->pMap, 0, stream->map_size); - stream->written = 0; - - return TRUE; -} - - -static INLINE void -os_stream_unmap(struct os_stream *stream) -{ - EngUnmapFile(stream->iFile); - if(stream->written < stream->map_size) { - /* Truncate file size */ - stream->pMap = EngMapFile(stream->wFileName, stream->written, &stream->iFile); - if(stream->pMap) - EngUnmapFile(stream->iFile); - } - - stream->pMap = NULL; -} - - -static INLINE void -os_stream_full_qualified_filename(char *dst, size_t size, const char *src) -{ - boolean need_drive, need_root; - - if((('A' <= src[0] && src[0] <= 'Z') || ('a' <= src[0] && src[0] <= 'z')) && src[1] == ':') { - need_drive = FALSE; - need_root = src[2] == '\\' ? FALSE : TRUE; - } - else { - need_drive = TRUE; - need_root = src[0] == '\\' ? FALSE : TRUE; - } - - snprintf(dst, size, - "\\??\\%s%s%s", - need_drive ? "C:" : "", - need_root ? "\\" : "", - src); -} - - -struct os_stream * -os_stream_create(const char *filename, size_t max_size) -{ - struct os_stream *stream; - - stream = CALLOC_STRUCT(os_stream); - if(!stream) - goto error1; - - os_stream_full_qualified_filename(stream->filename, - sizeof(stream->filename), - filename); - - if(max_size) { - stream->growable = FALSE; - stream->map_size = max_size; - } - else { - stream->growable = TRUE; - stream->map_size = MAP_FILE_SIZE; - } - - if(!os_stream_map(stream)) - goto error2; - - return stream; - -error2: - FREE(stream); -error1: - return NULL; -} - - -static INLINE void -os_stream_copy(struct os_stream *stream, const char *data, size_t size) -{ - assert(stream->written + size <= stream->map_size); - memcpy(stream->pMap + stream->written, data, size); - stream->written += size; -} - - -boolean -os_stream_write(struct os_stream *stream, const void *data, size_t size) -{ - if(!stream) - return FALSE; - - if(!stream->pMap) - return FALSE; - - while(stream->written + size > stream->map_size) { - size_t step = stream->map_size - stream->written; - os_stream_copy(stream, data, step); - data = (const char *)data + step; - size -= step; - - os_stream_unmap(stream); - if(!stream->growable || !os_stream_map(stream)) - return FALSE; - } - - os_stream_copy(stream, data, size); - - return TRUE; -} - - -void -os_stream_flush(struct os_stream *stream) -{ - (void)stream; -} - - -void -os_stream_close(struct os_stream *stream) -{ - if(!stream) - return; - - os_stream_unmap(stream); - - FREE(stream); -} - - -#endif diff --git a/src/gallium/auxiliary/util/u_blitter.c b/src/gallium/auxiliary/util/u_blitter.c index f3b4491d17..18f8606818 100644 --- a/src/gallium/auxiliary/util/u_blitter.c +++ b/src/gallium/auxiliary/util/u_blitter.c @@ -60,13 +60,12 @@ struct blitter_context_priv float vertices[4][2][4]; /**< {pos, color} or {pos, texcoord} */ /* Templates for various state objects. */ - struct pipe_depth_stencil_alpha_state template_dsa; struct pipe_sampler_state template_sampler_state; /* Constant state objects. */ /* Vertex shaders. */ void *vs_col; /**< Vertex shader which passes {pos, color} to the output */ - void *vs_tex; /**<Vertex shader which passes {pos, texcoord} to the output.*/ + void *vs_tex; /**< Vertex shader which passes {pos, texcoord} to the output.*/ /* Fragment shaders. */ /* FS which outputs a color to multiple color buffers. */ @@ -85,7 +84,7 @@ struct blitter_context_priv void *blend_keep_color; /**< blend state with writemask of 0 */ /* Depth stencil alpha state. */ - void *dsa_write_depth_stencil[0xff]; /**< indices are stencil clear values */ + void *dsa_write_depth_stencil; void *dsa_write_depth_keep_stencil; void *dsa_keep_depth_stencil; @@ -99,9 +98,9 @@ struct blitter_context_priv struct blitter_context *util_blitter_create(struct pipe_context *pipe) { struct blitter_context_priv *ctx; - struct pipe_blend_state blend; - struct pipe_depth_stencil_alpha_state *dsa; - struct pipe_rasterizer_state rs_state; + struct pipe_blend_state blend = { 0 }; + struct pipe_depth_stencil_alpha_state dsa = { { 0 } }; + struct pipe_rasterizer_state rs_state = { 0 }; struct pipe_sampler_state *sampler_state; unsigned i; @@ -122,30 +121,30 @@ struct blitter_context *util_blitter_create(struct pipe_context *pipe) ctx->blitter.saved_num_sampler_states = ~0; /* blend state objects */ - memset(&blend, 0, sizeof(blend)); ctx->blend_keep_color = pipe->create_blend_state(pipe, &blend); blend.rt[0].colormask = PIPE_MASK_RGBA; ctx->blend_write_color = pipe->create_blend_state(pipe, &blend); /* depth stencil alpha state objects */ - dsa = &ctx->template_dsa; ctx->dsa_keep_depth_stencil = - pipe->create_depth_stencil_alpha_state(pipe, dsa); + pipe->create_depth_stencil_alpha_state(pipe, &dsa); - dsa->depth.enabled = 1; - dsa->depth.writemask = 1; - dsa->depth.func = PIPE_FUNC_ALWAYS; + dsa.depth.enabled = 1; + dsa.depth.writemask = 1; + dsa.depth.func = PIPE_FUNC_ALWAYS; ctx->dsa_write_depth_keep_stencil = - pipe->create_depth_stencil_alpha_state(pipe, dsa); - - dsa->stencil[0].enabled = 1; - dsa->stencil[0].func = PIPE_FUNC_ALWAYS; - dsa->stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; - dsa->stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; - dsa->stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; - dsa->stencil[0].valuemask = 0xff; - dsa->stencil[0].writemask = 0xff; + pipe->create_depth_stencil_alpha_state(pipe, &dsa); + + dsa.stencil[0].enabled = 1; + dsa.stencil[0].func = PIPE_FUNC_ALWAYS; + dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; + dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; + dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; + dsa.stencil[0].valuemask = 0xff; + dsa.stencil[0].writemask = 0xff; + ctx->dsa_write_depth_stencil = + pipe->create_depth_stencil_alpha_state(pipe, &dsa); /* The DSA state objects which write depth and stencil are created * on-demand. */ @@ -210,11 +209,7 @@ void util_blitter_destroy(struct blitter_context *blitter) pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_keep_stencil); - - for (i = 0; i < 0xff; i++) - if (ctx->dsa_write_depth_stencil[i]) - pipe->delete_depth_stencil_alpha_state(pipe, - ctx->dsa_write_depth_stencil[i]); + pipe->delete_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); pipe->delete_rasterizer_state(pipe, ctx->rs_state); pipe->delete_vs_state(pipe, ctx->vs_col); @@ -266,6 +261,8 @@ static void blitter_restore_CSOs(struct blitter_context_priv *ctx) ctx->blitter.saved_fs = INVALID_PTR; ctx->blitter.saved_vs = INVALID_PTR; + pipe->set_stencil_ref(pipe, &ctx->blitter.saved_stencil_ref); + /* restore the state objects which are required to be saved before copy/fill */ if (ctx->blitter.saved_fb_state.nr_cbufs != ~0) { @@ -413,26 +410,6 @@ static void blitter_draw_quad(struct blitter_context_priv *ctx) } static INLINE -void *blitter_get_state_write_depth_stencil( - struct blitter_context_priv *ctx, - unsigned stencil) -{ - struct pipe_context *pipe = ctx->pipe; - - stencil &= 0xff; - - /* Create the DSA state on-demand. */ - if (!ctx->dsa_write_depth_stencil[stencil]) { - ctx->template_dsa.stencil[0].ref_value = stencil; - - ctx->dsa_write_depth_stencil[stencil] = - pipe->create_depth_stencil_alpha_state(pipe, &ctx->template_dsa); - } - - return ctx->dsa_write_depth_stencil[stencil]; -} - -static INLINE void **blitter_get_sampler_state(struct blitter_context_priv *ctx, int miplevel) { @@ -548,6 +525,7 @@ void util_blitter_clear(struct blitter_context *blitter, { struct blitter_context_priv *ctx = (struct blitter_context_priv*)blitter; struct pipe_context *pipe = ctx->pipe; + struct pipe_stencil_ref sr = { { 0 } }; assert(num_cbufs <= PIPE_MAX_COLOR_BUFS); @@ -559,9 +537,11 @@ void util_blitter_clear(struct blitter_context *blitter, else pipe->bind_blend_state(pipe, ctx->blend_keep_color); - if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) - pipe->bind_depth_stencil_alpha_state(pipe, - blitter_get_state_write_depth_stencil(ctx, stencil)); + if (clear_buffers & PIPE_CLEAR_DEPTHSTENCIL) { + sr.ref_value[0] = stencil & 0xff; + pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_write_depth_stencil); + pipe->set_stencil_ref(pipe, &sr); + } else pipe->bind_depth_stencil_alpha_state(pipe, ctx->dsa_keep_depth_stencil); diff --git a/src/gallium/auxiliary/util/u_blitter.h b/src/gallium/auxiliary/util/u_blitter.h index 3da5a6ca52..a2f17073ac 100644 --- a/src/gallium/auxiliary/util/u_blitter.h +++ b/src/gallium/auxiliary/util/u_blitter.h @@ -47,6 +47,7 @@ struct blitter_context void *saved_fs, *saved_vs; /**< fragment shader, vertex shader */ struct pipe_framebuffer_state saved_fb_state; /**< framebuffer state */ + struct pipe_stencil_ref saved_stencil_ref; /**< stencil ref */ int saved_num_sampler_states; void *saved_sampler_states[32]; @@ -170,6 +171,13 @@ void util_blitter_save_depth_stencil_alpha(struct blitter_context *blitter, } static INLINE +void util_blitter_save_stencil_ref(struct blitter_context *blitter, + const struct pipe_stencil_ref *state) +{ + blitter->saved_stencil_ref = *state; +} + +static INLINE void util_blitter_save_rasterizer(struct blitter_context *blitter, void *state) { diff --git a/src/gallium/auxiliary/util/u_debug.c b/src/gallium/auxiliary/util/u_debug.c index 4821b8a143..858d52c6ef 100644 --- a/src/gallium/auxiliary/util/u_debug.c +++ b/src/gallium/auxiliary/util/u_debug.c @@ -288,130 +288,13 @@ debug_dump_flags(const struct debug_named_value *names, } -static const struct debug_named_value pipe_format_names[] = { -#ifdef DEBUG - DEBUG_NAMED_VALUE(PIPE_FORMAT_NONE), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A1R5G5B5_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A4R4G4B4_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R5G6B5_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A2B10G10R10_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_I8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_L16_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR), - DEBUG_NAMED_VALUE(PIPE_FORMAT_YCBCR_REV), - DEBUG_NAMED_VALUE(PIPE_FORMAT_Z16_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_Z32_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_S8Z24_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24S8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_X8Z24_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_Z24X8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_S8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R64_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R64G64B64A64_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_FLOAT), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R32G32B32A32_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R16G16B16A16_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_UNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_USCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_B6G5R5_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A8B8G8R8_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_X8B8G8R8_SNORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SSCALED), - DEBUG_NAMED_VALUE(PIPE_FORMAT_L8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A8L8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8A8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_R8G8B8X8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_A8R8G8B8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_X8R8G8B8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8A8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_B8G8R8X8_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_X8UB8UG8SR8S_NORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_B6UG5SR5S_NORM), - DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_RGBA), - DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_RGBA), - DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_RGBA), - DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_SRGB), - DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT1_SRGBA), - DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT3_SRGBA), - DEBUG_NAMED_VALUE(PIPE_FORMAT_DXT5_SRGBA), -#endif - DEBUG_NAMED_VALUE_END -}; - #ifdef DEBUG void debug_print_format(const char *msg, unsigned fmt ) { - debug_printf("%s: %s\n", msg, debug_dump_enum(pipe_format_names, fmt)); + debug_printf("%s: %s\n", msg, util_format_name(fmt)); } #endif -const char *pf_name( enum pipe_format format ) -{ - return debug_dump_enum(pipe_format_names, format); -} - static const struct debug_named_value pipe_prim_names[] = { @@ -707,7 +590,7 @@ debug_dump_float_rgba_bmp(const char *filename, bmih.biClrUsed = 0; bmih.biClrImportant = 0; - stream = os_stream_create(filename, bmfh.bfSize); + stream = os_file_stream_create(filename); if(!stream) goto error1; diff --git a/src/gallium/auxiliary/util/u_dump.h b/src/gallium/auxiliary/util/u_dump.h new file mode 100644 index 0000000000..379f18ef38 --- /dev/null +++ b/src/gallium/auxiliary/util/u_dump.h @@ -0,0 +1,173 @@ +/************************************************************************** + * + * Copyright 2009 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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 VMWARE AND/OR ITS 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 + * Dump data in human/machine readable format. + * + * @author Jose Fonseca <jfonseca@vmware.com> + */ + +#ifndef U_DEBUG_DUMP_H_ +#define U_DEBUG_DUMP_H_ + + +#include "pipe/p_compiler.h" +#include "pipe/p_state.h" + + +#ifdef __cplusplus +extern "C" { +#endif + + +#define UTIL_DUMP_INVALID_NAME "<invalid>" + + +struct os_stream; + + +/* Duplicated here for convenience */ +extern struct os_stream * +os_log_stream; + + +/* + * p_defines.h + * + * XXX: These functions don't really dump anything -- just translate into + * strings so a verb better than "dump" should be used instead, in order to + * free up the namespace to the true dumper functions. + */ + +const char * +util_dump_blend_factor(unsigned value, boolean shortened); + +const char * +util_dump_blend_func(unsigned value, boolean shortened); + +const char * +util_dump_func(unsigned value, boolean shortened); + +const char * +util_dump_tex_target(unsigned value, boolean shortened); + +const char * +util_dump_tex_wrap(unsigned value, boolean shortened); + +const char * +util_dump_tex_mipfilter(unsigned value, boolean shortened); + +const char * +util_dump_tex_filter(unsigned value, boolean shortened); + + +/* + * p_state.h, through an os_stream + */ + +void +util_dump_template(struct os_stream *stream, + const struct pipe_texture *templat); + +void +util_dump_rasterizer_state(struct os_stream *stream, + const struct pipe_rasterizer_state *state); + +void +util_dump_poly_stipple(struct os_stream *stream, + const struct pipe_poly_stipple *state); + +void +util_dump_viewport_state(struct os_stream *stream, + const struct pipe_viewport_state *state); + +void +util_dump_scissor_state(struct os_stream *stream, + const struct pipe_scissor_state *state); + +void +util_dump_clip_state(struct os_stream *stream, + const struct pipe_clip_state *state); + +void +util_dump_shader_state(struct os_stream *stream, + const struct pipe_shader_state *state); + +void +util_dump_depth_stencil_alpha_state(struct os_stream *stream, + const struct pipe_depth_stencil_alpha_state *state); + +void +util_dump_rt_blend_state(struct os_stream *stream, + const struct pipe_rt_blend_state *state); + +void +util_dump_blend_state(struct os_stream *stream, + const struct pipe_blend_state *state); + +void +util_dump_blend_color(struct os_stream *stream, + const struct pipe_blend_color *state); + +void +util_dump_stencil_ref(struct os_stream *stream, + const struct pipe_stencil_ref *state); + +void +util_dump_framebuffer_state(struct os_stream *stream, + const struct pipe_framebuffer_state *state); + +void +util_dump_sampler_state(struct os_stream *stream, + const struct pipe_sampler_state *state); + +void +util_dump_surface(struct os_stream *stream, + const struct pipe_surface *state); + +void +util_dump_transfer(struct os_stream *stream, + const struct pipe_transfer *state); + +void +util_dump_vertex_buffer(struct os_stream *stream, + const struct pipe_vertex_buffer *state); + +void +util_dump_vertex_element(struct os_stream *stream, + const struct pipe_vertex_element *state); + + +/* FIXME: Move the other debug_dump_xxx functions out of u_debug.h into here. */ + + +#ifdef __cplusplus +} +#endif + +#endif /* U_DEBUG_H_ */ diff --git a/src/gallium/auxiliary/util/u_debug_dump.c b/src/gallium/auxiliary/util/u_dump_defines.c index 61624d05c0..96a2256347 100644 --- a/src/gallium/auxiliary/util/u_debug_dump.c +++ b/src/gallium/auxiliary/util/u_dump_defines.c @@ -28,15 +28,12 @@ #include "util/u_memory.h" #include "util/u_debug.h" -#include "util/u_debug_dump.h" - - -#define DEBUG_DUMP_INVALID_NAME "<invalid>" +#include "util/u_dump.h" #if 0 static const char * -debug_dump_strip_prefix(const char *name, +util_dump_strip_prefix(const char *name, const char *prefix) { const char *stripped; @@ -55,30 +52,30 @@ debug_dump_strip_prefix(const char *name, #endif static const char * -debug_dump_enum_continuous(unsigned value, +util_dump_enum_continuous(unsigned value, unsigned num_names, const char **names) { if (value >= num_names) - return DEBUG_DUMP_INVALID_NAME; + return UTIL_DUMP_INVALID_NAME; return names[value]; } -#define DEFINE_DEBUG_DUMP_CONTINUOUS(_name) \ +#define DEFINE_UTIL_DUMP_CONTINUOUS(_name) \ const char * \ - debug_dump_##_name(unsigned value, boolean shortened) \ + util_dump_##_name(unsigned value, boolean shortened) \ { \ if(shortened) \ - return debug_dump_enum_continuous(value, Elements(debug_dump_##_name##_short_names), debug_dump_##_name##_short_names); \ + return util_dump_enum_continuous(value, Elements(util_dump_##_name##_short_names), util_dump_##_name##_short_names); \ else \ - return debug_dump_enum_continuous(value, Elements(debug_dump_##_name##_names), debug_dump_##_name##_names); \ + return util_dump_enum_continuous(value, Elements(util_dump_##_name##_names), util_dump_##_name##_names); \ } static const char * -debug_dump_blend_factor_names[] = { - DEBUG_DUMP_INVALID_NAME, /* 0x0 */ +util_dump_blend_factor_names[] = { + UTIL_DUMP_INVALID_NAME, /* 0x0 */ "PIPE_BLENDFACTOR_ONE", "PIPE_BLENDFACTOR_SRC_COLOR", "PIPE_BLENDFACTOR_SRC_ALPHA", @@ -89,18 +86,18 @@ debug_dump_blend_factor_names[] = { "PIPE_BLENDFACTOR_CONST_ALPHA", "PIPE_BLENDFACTOR_SRC1_COLOR", "PIPE_BLENDFACTOR_SRC1_ALPHA", - DEBUG_DUMP_INVALID_NAME, /* 0x0b */ - DEBUG_DUMP_INVALID_NAME, /* 0x0c */ - DEBUG_DUMP_INVALID_NAME, /* 0x0d */ - DEBUG_DUMP_INVALID_NAME, /* 0x0e */ - DEBUG_DUMP_INVALID_NAME, /* 0x0f */ - DEBUG_DUMP_INVALID_NAME, /* 0x10 */ + UTIL_DUMP_INVALID_NAME, /* 0x0b */ + UTIL_DUMP_INVALID_NAME, /* 0x0c */ + UTIL_DUMP_INVALID_NAME, /* 0x0d */ + UTIL_DUMP_INVALID_NAME, /* 0x0e */ + UTIL_DUMP_INVALID_NAME, /* 0x0f */ + UTIL_DUMP_INVALID_NAME, /* 0x10 */ "PIPE_BLENDFACTOR_ZERO", "PIPE_BLENDFACTOR_INV_SRC_COLOR", "PIPE_BLENDFACTOR_INV_SRC_ALPHA", "PIPE_BLENDFACTOR_INV_DST_ALPHA", "PIPE_BLENDFACTOR_INV_DST_COLOR", - DEBUG_DUMP_INVALID_NAME, /* 0x16 */ + UTIL_DUMP_INVALID_NAME, /* 0x16 */ "PIPE_BLENDFACTOR_INV_CONST_COLOR", "PIPE_BLENDFACTOR_INV_CONST_ALPHA", "PIPE_BLENDFACTOR_INV_SRC1_COLOR", @@ -108,8 +105,8 @@ debug_dump_blend_factor_names[] = { }; static const char * -debug_dump_blend_factor_short_names[] = { - DEBUG_DUMP_INVALID_NAME, /* 0x0 */ +util_dump_blend_factor_short_names[] = { + UTIL_DUMP_INVALID_NAME, /* 0x0 */ "one", "src_color", "src_alpha", @@ -120,29 +117,29 @@ debug_dump_blend_factor_short_names[] = { "const_alpha", "src1_color", "src1_alpha", - DEBUG_DUMP_INVALID_NAME, /* 0x0b */ - DEBUG_DUMP_INVALID_NAME, /* 0x0c */ - DEBUG_DUMP_INVALID_NAME, /* 0x0d */ - DEBUG_DUMP_INVALID_NAME, /* 0x0e */ - DEBUG_DUMP_INVALID_NAME, /* 0x0f */ - DEBUG_DUMP_INVALID_NAME, /* 0x10 */ + UTIL_DUMP_INVALID_NAME, /* 0x0b */ + UTIL_DUMP_INVALID_NAME, /* 0x0c */ + UTIL_DUMP_INVALID_NAME, /* 0x0d */ + UTIL_DUMP_INVALID_NAME, /* 0x0e */ + UTIL_DUMP_INVALID_NAME, /* 0x0f */ + UTIL_DUMP_INVALID_NAME, /* 0x10 */ "zero", "inv_src_color", "inv_src_alpha", "inv_dst_alpha", "inv_dst_color", - DEBUG_DUMP_INVALID_NAME, /* 0x16 */ + UTIL_DUMP_INVALID_NAME, /* 0x16 */ "inv_const_color", "inv_const_alpha", "inv_src1_color", "inv_src1_alpha" }; -DEFINE_DEBUG_DUMP_CONTINUOUS(blend_factor) +DEFINE_UTIL_DUMP_CONTINUOUS(blend_factor) static const char * -debug_dump_blend_func_names[] = { +util_dump_blend_func_names[] = { "PIPE_BLEND_ADD", "PIPE_BLEND_SUBTRACT", "PIPE_BLEND_REVERSE_SUBTRACT", @@ -151,7 +148,7 @@ debug_dump_blend_func_names[] = { }; static const char * -debug_dump_blend_func_short_names[] = { +util_dump_blend_func_short_names[] = { "add", "sub", "rev_sub", @@ -159,11 +156,11 @@ debug_dump_blend_func_short_names[] = { "max" }; -DEFINE_DEBUG_DUMP_CONTINUOUS(blend_func) +DEFINE_UTIL_DUMP_CONTINUOUS(blend_func) static const char * -debug_dump_func_names[] = { +util_dump_func_names[] = { "PIPE_FUNC_NEVER", "PIPE_FUNC_LESS", "PIPE_FUNC_EQUAL", @@ -175,7 +172,7 @@ debug_dump_func_names[] = { }; static const char * -debug_dump_func_short_names[] = { +util_dump_func_short_names[] = { "never", "less", "equal", @@ -186,11 +183,11 @@ debug_dump_func_short_names[] = { "always" }; -DEFINE_DEBUG_DUMP_CONTINUOUS(func) +DEFINE_UTIL_DUMP_CONTINUOUS(func) static const char * -debug_dump_tex_target_names[] = { +util_dump_tex_target_names[] = { "PIPE_TEXTURE_1D", "PIPE_TEXTURE_2D", "PIPE_TEXTURE_3D", @@ -198,18 +195,18 @@ debug_dump_tex_target_names[] = { }; static const char * -debug_dump_tex_target_short_names[] = { +util_dump_tex_target_short_names[] = { "1d", "2d", "3d", "cube" }; -DEFINE_DEBUG_DUMP_CONTINUOUS(tex_target) +DEFINE_UTIL_DUMP_CONTINUOUS(tex_target) static const char * -debug_dump_tex_wrap_names[] = { +util_dump_tex_wrap_names[] = { "PIPE_TEX_WRAP_REPEAT", "PIPE_TEX_WRAP_CLAMP", "PIPE_TEX_WRAP_CLAMP_TO_EDGE", @@ -221,7 +218,7 @@ debug_dump_tex_wrap_names[] = { }; static const char * -debug_dump_tex_wrap_short_names[] = { +util_dump_tex_wrap_short_names[] = { "repeat", "clamp", "clamp_to_edge", @@ -232,36 +229,36 @@ debug_dump_tex_wrap_short_names[] = { "mirror_clamp_to_border" }; -DEFINE_DEBUG_DUMP_CONTINUOUS(tex_wrap) +DEFINE_UTIL_DUMP_CONTINUOUS(tex_wrap) static const char * -debug_dump_tex_mipfilter_names[] = { +util_dump_tex_mipfilter_names[] = { "PIPE_TEX_MIPFILTER_NEAREST", "PIPE_TEX_MIPFILTER_LINEAR", "PIPE_TEX_MIPFILTER_NONE" }; static const char * -debug_dump_tex_mipfilter_short_names[] = { +util_dump_tex_mipfilter_short_names[] = { "nearest", "linear", "none" }; -DEFINE_DEBUG_DUMP_CONTINUOUS(tex_mipfilter) +DEFINE_UTIL_DUMP_CONTINUOUS(tex_mipfilter) static const char * -debug_dump_tex_filter_names[] = { +util_dump_tex_filter_names[] = { "PIPE_TEX_FILTER_NEAREST", "PIPE_TEX_FILTER_LINEAR" }; static const char * -debug_dump_tex_filter_short_names[] = { +util_dump_tex_filter_short_names[] = { "nearest", "linear" }; -DEFINE_DEBUG_DUMP_CONTINUOUS(tex_filter) +DEFINE_UTIL_DUMP_CONTINUOUS(tex_filter) diff --git a/src/gallium/auxiliary/util/u_dump_state.c b/src/gallium/auxiliary/util/u_dump_state.c new file mode 100644 index 0000000000..eaf4ec90f2 --- /dev/null +++ b/src/gallium/auxiliary/util/u_dump_state.c @@ -0,0 +1,709 @@ +/************************************************************************** + * + * Copyright 2008-2010 VMware, Inc. + * All Rights Reserved. + * + * Permission is hereby granted, free of charge, to any person obtaining a + * copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, 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 VMWARE AND/OR ITS 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. + * + **************************************************************************/ + + +#include "pipe/p_compiler.h" +#include "os/os_stream.h" +#include "util/u_memory.h" +#include "util/u_string.h" +#include "util/u_format.h" +#include "tgsi/tgsi_dump.h" + +#include "u_dump.h" + + +/* + * Dump primitives + */ + +static INLINE void +util_stream_writef(struct os_stream *stream, const char *format, ...) +{ + static char buf[1024]; + unsigned len; + va_list ap; + va_start(ap, format); + len = util_vsnprintf(buf, sizeof(buf), format, ap); + va_end(ap); + os_stream_write(stream, buf, len); +} + +static void +util_dump_bool(struct os_stream *stream, int value) +{ + util_stream_writef(stream, "%c", value ? '1' : '0'); +} + +static void +util_dump_int(struct os_stream *stream, long long int value) +{ + util_stream_writef(stream, "%lli", value); +} + +static void +util_dump_uint(struct os_stream *stream, long long unsigned value) +{ + util_stream_writef(stream, "%llu", value); +} + +static void +util_dump_float(struct os_stream *stream, double value) +{ + util_stream_writef(stream, "%g", value); +} + +static void +util_dump_string(struct os_stream *stream, const char *str) +{ + os_stream_write_str(stream, "\""); + os_stream_write_str(stream, str); + os_stream_write_str(stream, "\""); +} + +static void +util_dump_enum(struct os_stream *stream, const char *value) +{ + os_stream_write_str(stream, value); +} + +static void +util_dump_array_begin(struct os_stream *stream) +{ + os_stream_write_str(stream, "{"); +} + +static void +util_dump_array_end(struct os_stream *stream) +{ + os_stream_write_str(stream, "}"); +} + +static void +util_dump_elem_begin(struct os_stream *stream) +{ +} + +static void +util_dump_elem_end(struct os_stream *stream) +{ + os_stream_write_str(stream, ", "); +} + +static void +util_dump_struct_begin(struct os_stream *stream, const char *name) +{ + os_stream_write_str(stream, "{"); +} + +static void +util_dump_struct_end(struct os_stream *stream) +{ + os_stream_write_str(stream, "}"); +} + +static void +util_dump_member_begin(struct os_stream *stream, const char *name) +{ + util_stream_writef(stream, "%s = ", name); +} + +static void +util_dump_member_end(struct os_stream *stream) +{ + os_stream_write_str(stream, ", "); +} + +static void +util_dump_null(struct os_stream *stream) +{ + os_stream_write_str(stream, "NULL"); +} + +static void +util_dump_ptr(struct os_stream *stream, const void *value) +{ + if(value) + util_stream_writef(stream, "0x%08lx", (unsigned long)(uintptr_t)value); + else + util_dump_null(stream); +} + + +/* + * Code saving macros. + */ + +#define util_dump_arg(_stream, _type, _arg) \ + do { \ + util_dump_arg_begin(_stream, #_arg); \ + util_dump_##_type(_stream, _arg); \ + util_dump_arg_end(_stream); \ + } while(0) + +#define util_dump_ret(_stream, _type, _arg) \ + do { \ + util_dump_ret_begin(_stream); \ + util_dump_##_type(_stream, _arg); \ + util_dump_ret_end(_stream); \ + } while(0) + +#define util_dump_array(_stream, _type, _obj, _size) \ + do { \ + size_t idx; \ + util_dump_array_begin(_stream); \ + for(idx = 0; idx < (_size); ++idx) { \ + util_dump_elem_begin(_stream); \ + util_dump_##_type(_stream, (_obj)[idx]); \ + util_dump_elem_end(_stream); \ + } \ + util_dump_array_end(_stream); \ + } while(0) + +#define util_dump_struct_array(_stream, _type, _obj, _size) \ + do { \ + size_t idx; \ + util_dump_array_begin(_stream); \ + for(idx = 0; idx < (_size); ++idx) { \ + util_dump_elem_begin(_stream); \ + util_dump_##_type(_stream, &(_obj)[idx]); \ + util_dump_elem_end(_stream); \ + } \ + util_dump_array_end(_stream); \ + } while(0) + +#define util_dump_member(_stream, _type, _obj, _member) \ + do { \ + util_dump_member_begin(_stream, #_member); \ + util_dump_##_type(_stream, (_obj)->_member); \ + util_dump_member_end(_stream); \ + } while(0) + +#define util_dump_arg_array(_stream, _type, _arg, _size) \ + do { \ + util_dump_arg_begin(_stream, #_arg); \ + util_dump_array(_stream, _type, _arg, _size); \ + util_dump_arg_end(_stream); \ + } while(0) + +#define util_dump_member_array(_stream, _type, _obj, _member) \ + do { \ + util_dump_member_begin(_stream, #_member); \ + util_dump_array(_stream, _type, (_obj)->_member, sizeof((_obj)->_member)/sizeof((_obj)->_member[0])); \ + util_dump_member_end(_stream); \ + } while(0) + + + +/* + * Wrappers for enum -> string dumpers. + */ + + +static void +util_dump_format(struct os_stream *stream, enum pipe_format format) +{ + util_dump_enum(stream, util_format_name(format)); +} + + +static void +util_dump_enum_blend_factor(struct os_stream *stream, unsigned value) +{ + util_dump_enum(stream, util_dump_blend_factor(value, TRUE)); +} + +static void +util_dump_enum_blend_func(struct os_stream *stream, unsigned value) +{ + util_dump_enum(stream, util_dump_blend_func(value, TRUE)); +} + +static void +util_dump_enum_func(struct os_stream *stream, unsigned value) +{ + util_dump_enum(stream, util_dump_func(value, TRUE)); +} + + +/* + * Public functions + */ + + +void +util_dump_template(struct os_stream *stream, const struct pipe_texture *templat) +{ + if(!templat) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_texture"); + + util_dump_member(stream, int, templat, target); + util_dump_member(stream, format, templat, format); + + util_dump_member_begin(stream, "width"); + util_dump_uint(stream, templat->width0); + util_dump_member_end(stream); + + util_dump_member_begin(stream, "height"); + util_dump_uint(stream, templat->height0); + util_dump_member_end(stream); + + util_dump_member_begin(stream, "depth"); + util_dump_uint(stream, templat->depth0); + util_dump_member_end(stream); + + util_dump_member(stream, uint, templat, last_level); + util_dump_member(stream, uint, templat, tex_usage); + + util_dump_struct_end(stream); +} + + +void +util_dump_rasterizer_state(struct os_stream *stream, const struct pipe_rasterizer_state *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_rasterizer_state"); + + util_dump_member(stream, bool, state, flatshade); + util_dump_member(stream, bool, state, light_twoside); + util_dump_member(stream, uint, state, front_winding); + util_dump_member(stream, uint, state, cull_mode); + util_dump_member(stream, uint, state, fill_cw); + util_dump_member(stream, uint, state, fill_ccw); + util_dump_member(stream, bool, state, offset_cw); + util_dump_member(stream, bool, state, offset_ccw); + util_dump_member(stream, bool, state, scissor); + util_dump_member(stream, bool, state, poly_smooth); + util_dump_member(stream, bool, state, poly_stipple_enable); + util_dump_member(stream, bool, state, point_smooth); + util_dump_member(stream, uint, state, sprite_coord_enable); + util_dump_member(stream, bool, state, sprite_coord_mode); + util_dump_member(stream, bool, state, point_quad_rasterization); + util_dump_member(stream, bool, state, point_size_per_vertex); + util_dump_member(stream, bool, state, multisample); + util_dump_member(stream, bool, state, line_smooth); + util_dump_member(stream, bool, state, line_stipple_enable); + util_dump_member(stream, uint, state, line_stipple_factor); + util_dump_member(stream, uint, state, line_stipple_pattern); + util_dump_member(stream, bool, state, line_last_pixel); + util_dump_member(stream, bool, state, bypass_vs_clip_and_viewport); + util_dump_member(stream, bool, state, flatshade_first); + util_dump_member(stream, bool, state, gl_rasterization_rules); + + util_dump_member(stream, float, state, line_width); + util_dump_member(stream, float, state, point_size); + util_dump_member(stream, float, state, offset_units); + util_dump_member(stream, float, state, offset_scale); + + util_dump_struct_end(stream); +} + + +void +util_dump_poly_stipple(struct os_stream *stream, const struct pipe_poly_stipple *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_poly_stipple"); + + util_dump_member_begin(stream, "stipple"); + util_dump_member_array(stream, uint, state, stipple); + util_dump_member_end(stream); + + util_dump_struct_end(stream); +} + + +void +util_dump_viewport_state(struct os_stream *stream, const struct pipe_viewport_state *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_viewport_state"); + + util_dump_member_array(stream, float, state, scale); + util_dump_member_array(stream, float, state, translate); + + util_dump_struct_end(stream); +} + + +void +util_dump_scissor_state(struct os_stream *stream, const struct pipe_scissor_state *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_scissor_state"); + + util_dump_member(stream, uint, state, minx); + util_dump_member(stream, uint, state, miny); + util_dump_member(stream, uint, state, maxx); + util_dump_member(stream, uint, state, maxy); + + util_dump_struct_end(stream); +} + + +void +util_dump_clip_state(struct os_stream *stream, const struct pipe_clip_state *state) +{ + unsigned i; + + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_clip_state"); + + util_dump_member_begin(stream, "ucp"); + util_dump_array_begin(stream); + for(i = 0; i < PIPE_MAX_CLIP_PLANES; ++i) { + util_dump_elem_begin(stream); + util_dump_array(stream, float, state->ucp[i], 4); + util_dump_elem_end(stream); + } + util_dump_array_end(stream); + util_dump_member_end(stream); + + util_dump_member(stream, uint, state, nr); + + util_dump_struct_end(stream); +} + + +void +util_dump_shader_state(struct os_stream *stream, const struct pipe_shader_state *state) +{ + char str[8192]; + + if(!state) { + util_dump_null(stream); + return; + } + + tgsi_dump_str(state->tokens, 0, str, sizeof(str)); + + util_dump_struct_begin(stream, "pipe_shader_state"); + + util_dump_member_begin(stream, "tokens"); + util_dump_string(stream, str); + util_dump_member_end(stream); + + util_dump_struct_end(stream); +} + + +void +util_dump_depth_stencil_alpha_state(struct os_stream *stream, const struct pipe_depth_stencil_alpha_state *state) +{ + unsigned i; + + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_depth_stencil_alpha_state"); + + util_dump_member_begin(stream, "depth"); + util_dump_struct_begin(stream, "pipe_depth_state"); + util_dump_member(stream, bool, &state->depth, enabled); + if (state->depth.enabled) { + util_dump_member(stream, bool, &state->depth, writemask); + util_dump_member(stream, enum_func, &state->depth, func); + } + util_dump_struct_end(stream); + util_dump_member_end(stream); + + util_dump_member_begin(stream, "stencil"); + util_dump_array_begin(stream); + for(i = 0; i < Elements(state->stencil); ++i) { + util_dump_elem_begin(stream); + util_dump_struct_begin(stream, "pipe_stencil_state"); + util_dump_member(stream, bool, &state->stencil[i], enabled); + if (state->stencil[i].enabled) { + util_dump_member(stream, enum_func, &state->stencil[i], func); + util_dump_member(stream, uint, &state->stencil[i], fail_op); + util_dump_member(stream, uint, &state->stencil[i], zpass_op); + util_dump_member(stream, uint, &state->stencil[i], zfail_op); + util_dump_member(stream, uint, &state->stencil[i], valuemask); + util_dump_member(stream, uint, &state->stencil[i], writemask); + } + util_dump_struct_end(stream); + util_dump_elem_end(stream); + } + util_dump_array_end(stream); + util_dump_member_end(stream); + + util_dump_member_begin(stream, "alpha"); + util_dump_struct_begin(stream, "pipe_alpha_state"); + util_dump_member(stream, bool, &state->alpha, enabled); + if (state->alpha.enabled) { + util_dump_member(stream, enum_func, &state->alpha, func); + util_dump_member(stream, float, &state->alpha, ref_value); + } + util_dump_struct_end(stream); + util_dump_member_end(stream); + + util_dump_struct_end(stream); +} + +void +util_dump_rt_blend_state(struct os_stream *stream, const struct pipe_rt_blend_state *state) +{ + util_dump_struct_begin(stream, "pipe_rt_blend_state"); + + util_dump_member(stream, uint, state, blend_enable); + if (state->blend_enable) { + util_dump_member(stream, enum_blend_func, state, rgb_func); + util_dump_member(stream, enum_blend_factor, state, rgb_src_factor); + util_dump_member(stream, enum_blend_factor, state, rgb_dst_factor); + + util_dump_member(stream, enum_blend_func, state, alpha_func); + util_dump_member(stream, enum_blend_factor, state, alpha_src_factor); + util_dump_member(stream, enum_blend_factor, state, alpha_dst_factor); + } + + util_dump_member(stream, uint, state, colormask); + + util_dump_struct_end(stream); +} + +void +util_dump_blend_state(struct os_stream *stream, const struct pipe_blend_state *state) +{ + unsigned valid_entries = 1; + + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_blend_state"); + + util_dump_member(stream, bool, state, dither); + + util_dump_member(stream, bool, state, logicop_enable); + if (state->logicop_enable) { + util_dump_member(stream, enum_func, state, logicop_func); + } + else { + util_dump_member(stream, bool, state, independent_blend_enable); + + util_dump_member_begin(stream, "rt"); + if (state->independent_blend_enable) + valid_entries = PIPE_MAX_COLOR_BUFS; + util_dump_struct_array(stream, rt_blend_state, state->rt, valid_entries); + util_dump_member_end(stream); + } + + util_dump_struct_end(stream); +} + + +void +util_dump_blend_color(struct os_stream *stream, const struct pipe_blend_color *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_blend_color"); + + util_dump_member_array(stream, float, state, color); + + util_dump_struct_end(stream); +} + +void +util_dump_stencil_ref(struct os_stream *stream, const struct pipe_stencil_ref *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_stencil_ref"); + + util_dump_member_array(stream, uint, state, ref_value); + + util_dump_struct_end(stream); +} + +void +util_dump_framebuffer_state(struct os_stream *stream, const struct pipe_framebuffer_state *state) +{ + util_dump_struct_begin(stream, "pipe_framebuffer_state"); + + util_dump_member(stream, uint, state, width); + util_dump_member(stream, uint, state, height); + util_dump_member(stream, uint, state, nr_cbufs); + util_dump_member_array(stream, ptr, state, cbufs); + util_dump_member(stream, ptr, state, zsbuf); + + util_dump_struct_end(stream); +} + + +void +util_dump_sampler_state(struct os_stream *stream, const struct pipe_sampler_state *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_sampler_state"); + + util_dump_member(stream, uint, state, wrap_s); + util_dump_member(stream, uint, state, wrap_t); + util_dump_member(stream, uint, state, wrap_r); + util_dump_member(stream, uint, state, min_img_filter); + util_dump_member(stream, uint, state, min_mip_filter); + util_dump_member(stream, uint, state, mag_img_filter); + util_dump_member(stream, uint, state, compare_mode); + util_dump_member(stream, enum_func, state, compare_func); + util_dump_member(stream, bool, state, normalized_coords); + util_dump_member(stream, uint, state, max_anisotropy); + util_dump_member(stream, float, state, lod_bias); + util_dump_member(stream, float, state, min_lod); + util_dump_member(stream, float, state, max_lod); + util_dump_member_array(stream, float, state, border_color); + + util_dump_struct_end(stream); +} + + +void +util_dump_surface(struct os_stream *stream, const struct pipe_surface *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_surface"); + + util_dump_member(stream, format, state, format); + util_dump_member(stream, uint, state, width); + util_dump_member(stream, uint, state, height); + + util_dump_member(stream, uint, state, layout); + util_dump_member(stream, uint, state, offset); + util_dump_member(stream, uint, state, usage); + + util_dump_member(stream, ptr, state, texture); + util_dump_member(stream, uint, state, face); + util_dump_member(stream, uint, state, level); + util_dump_member(stream, uint, state, zslice); + + util_dump_struct_end(stream); +} + + +void +util_dump_transfer(struct os_stream *stream, const struct pipe_transfer *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_transfer"); + + util_dump_member(stream, uint, state, width); + util_dump_member(stream, uint, state, height); + + util_dump_member(stream, uint, state, stride); + util_dump_member(stream, uint, state, usage); + + util_dump_member(stream, ptr, state, texture); + util_dump_member(stream, uint, state, face); + util_dump_member(stream, uint, state, level); + util_dump_member(stream, uint, state, zslice); + + util_dump_struct_end(stream); +} + + +void +util_dump_vertex_buffer(struct os_stream *stream, const struct pipe_vertex_buffer *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_vertex_buffer"); + + util_dump_member(stream, uint, state, stride); + util_dump_member(stream, uint, state, max_index); + util_dump_member(stream, uint, state, buffer_offset); + util_dump_member(stream, ptr, state, buffer); + + util_dump_struct_end(stream); +} + + +void +util_dump_vertex_element(struct os_stream *stream, const struct pipe_vertex_element *state) +{ + if(!state) { + util_dump_null(stream); + return; + } + + util_dump_struct_begin(stream, "pipe_vertex_element"); + + util_dump_member(stream, uint, state, src_offset); + + util_dump_member(stream, uint, state, vertex_buffer_index); + util_dump_member(stream, uint, state, nr_components); + + util_dump_member(stream, format, state, src_format); + + util_dump_struct_end(stream); +} diff --git a/src/gallium/auxiliary/util/u_format.h b/src/gallium/auxiliary/util/u_format.h index 4323bc881b..2fbbb83d4b 100644 --- a/src/gallium/auxiliary/util/u_format.h +++ b/src/gallium/auxiliary/util/u_format.h @@ -156,6 +156,19 @@ util_format_description(enum pipe_format format); * Format query functions. */ +static INLINE const char * +util_format_name(enum pipe_format format) +{ + const struct util_format_description *desc = util_format_description(format); + + assert(format); + if (!format) { + return "???"; + } + + return desc->name; +} + static INLINE boolean util_format_is_compressed(enum pipe_format format) { diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst index a7669575b9..9080addba4 100644 --- a/src/gallium/docs/source/context.rst +++ b/src/gallium/docs/source/context.rst @@ -49,8 +49,9 @@ Non-CSO State These pieces of state are too small, variable, and/or trivial to have CSO objects. They all follow simple, one-method binding calls, e.g. -``set_edgeflags``. - +``set_blend_color``. +* ``set_stencil_ref`` sets the stencil front and back reference values + which are used as comparison values in stencil test. * ``set_blend_color`` * ``set_clip_state`` * ``set_polygon_stipple`` diff --git a/src/gallium/docs/source/cso/dsa.rst b/src/gallium/docs/source/cso/dsa.rst index 12abaa9d6f..1bbe381f9e 100644 --- a/src/gallium/docs/source/cso/dsa.rst +++ b/src/gallium/docs/source/cso/dsa.rst @@ -11,9 +11,9 @@ they are all stored in one structure. During actual execution, the order of operations done on fragments is always: +* Alpha * Stencil * Depth -* Alpha Depth Members ------------- @@ -28,15 +28,18 @@ func Stencil Members --------------- -XXX document valuemask, writemask - enabled Whether the stencil test is enabled. For the second stencil, whether the - two-sided stencil is enabled. + two-sided stencil is enabled. If two-sided stencil is disabled, the other + fields for the second array member are not valid. func The stencil test function. One of PIPE_FUNC. -ref_value - Stencil test reference value; used for certain functions. +valuemask + Stencil test value mask; this is ANDed with the value in the stencil + buffer and the reference value before doing the stencil comparison test. +writemask + Stencil test writemask; this controls which bits of the stencil buffer + are written. fail_op The operation to carry out if the stencil test fails. One of PIPE_STENCIL_OP. diff --git a/src/gallium/docs/source/cso/sampler.rst b/src/gallium/docs/source/cso/sampler.rst index 044ffffcb4..77979fc44d 100644 --- a/src/gallium/docs/source/cso/sampler.rst +++ b/src/gallium/docs/source/cso/sampler.rst @@ -45,4 +45,6 @@ border_color RGBA color used for out-of-bounds coordinates. max_anisotropy Maximum filtering to apply anisotropically to textures. Setting this to - 1.0 effectively disables anisotropic filtering. + 0 disables anisotropic filtering. Any other setting enables anisotropic + filtering, however it's not unexpected some drivers only will change their + filtering with a setting of 2 and higher. diff --git a/src/gallium/drivers/cell/common.h b/src/gallium/drivers/cell/common.h index 7f2b33c2dc..bbb112fd33 100644 --- a/src/gallium/drivers/cell/common.h +++ b/src/gallium/drivers/cell/common.h @@ -230,6 +230,7 @@ struct cell_command_rasterizer { opcode_t opcode; /**< CELL_CMD_STATE_RASTERIZER */ struct pipe_rasterizer_state rasterizer; + uint32_t pad[1]; }; @@ -326,7 +327,7 @@ struct cell_command_sampler opcode_t opcode; /**< CELL_CMD_STATE_SAMPLER */ uint unit; struct pipe_sampler_state state; - uint32_t pad_[2]; + uint32_t pad_[3]; }; diff --git a/src/gallium/drivers/cell/ppu/cell_context.h b/src/gallium/drivers/cell/ppu/cell_context.h index 905cd5db39..a77cc5b906 100644 --- a/src/gallium/drivers/cell/ppu/cell_context.h +++ b/src/gallium/drivers/cell/ppu/cell_context.h @@ -114,6 +114,7 @@ struct cell_context struct spe_function logic_op; struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; struct pipe_buffer *constants[2]; struct pipe_framebuffer_state framebuffer; diff --git a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c index 0dab34075d..70683bb367 100644 --- a/src/gallium/drivers/cell/ppu/cell_gen_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_gen_fragment.c @@ -1175,7 +1175,8 @@ gen_colormask(struct spe_function *f, */ static void gen_stencil_test(struct spe_function *f, - const struct pipe_stencil_state *state, + const struct pipe_stencil_state *state, + const unsigned ref_value, uint stencil_max_value, int fragment_mask_reg, int fbS_reg, @@ -1189,7 +1190,7 @@ gen_stencil_test(struct spe_function *f, case PIPE_FUNC_EQUAL: if (state->valuemask == stencil_max_value) { /* stencil_pass = fragment_mask & (s == reference) */ - spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, state->ref_value); + spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, ref_value); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); } else { @@ -1197,7 +1198,7 @@ gen_stencil_test(struct spe_function *f, uint tmp_masked_stencil = spe_allocate_available_register(f); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil, - state->valuemask & state->ref_value); + state->valuemask & ref_value); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_masked_stencil); } @@ -1206,7 +1207,7 @@ gen_stencil_test(struct spe_function *f, case PIPE_FUNC_NOTEQUAL: if (state->valuemask == stencil_max_value) { /* stencil_pass = fragment_mask & ~(s == reference) */ - spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, state->ref_value); + spe_compare_equal_uint(f, stencil_pass_reg, fbS_reg, ref_value); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); } else { @@ -1214,7 +1215,7 @@ gen_stencil_test(struct spe_function *f, int tmp_masked_stencil = spe_allocate_available_register(f); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_compare_equal_uint(f, stencil_pass_reg, tmp_masked_stencil, - state->valuemask & state->ref_value); + state->valuemask & ref_value); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_masked_stencil); } @@ -1223,7 +1224,7 @@ gen_stencil_test(struct spe_function *f, case PIPE_FUNC_LESS: if (state->valuemask == stencil_max_value) { /* stencil_pass = fragment_mask & (reference < s) */ - spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, state->ref_value); + spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, ref_value); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); } else { @@ -1231,7 +1232,7 @@ gen_stencil_test(struct spe_function *f, int tmp_masked_stencil = spe_allocate_available_register(f); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil, - state->valuemask & state->ref_value); + state->valuemask & ref_value); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_masked_stencil); } @@ -1246,7 +1247,7 @@ gen_stencil_test(struct spe_function *f, * treats its operands as unsigned - no sign extension. */ int tmp_reg = spe_allocate_available_register(f); - spe_load_uint(f, tmp_reg, state->ref_value); + spe_load_uint(f, tmp_reg, ref_value); spe_clgt(f, stencil_pass_reg, tmp_reg, fbS_reg); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_reg); @@ -1255,7 +1256,7 @@ gen_stencil_test(struct spe_function *f, /* stencil_pass = fragment_mask & ((reference&mask) > (s&mask)) */ int tmp_reg = spe_allocate_available_register(f); int tmp_masked_stencil = spe_allocate_available_register(f); - spe_load_uint(f, tmp_reg, state->valuemask & state->ref_value); + spe_load_uint(f, tmp_reg, state->valuemask & ref_value); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_clgt(f, stencil_pass_reg, tmp_reg, tmp_masked_stencil); spe_and(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); @@ -1269,7 +1270,7 @@ gen_stencil_test(struct spe_function *f, /* stencil_pass = fragment_mask & (reference >= s) * = fragment_mask & ~(s > reference) */ spe_compare_greater_uint(f, stencil_pass_reg, fbS_reg, - state->ref_value); + ref_value); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); } else { @@ -1277,7 +1278,7 @@ gen_stencil_test(struct spe_function *f, int tmp_masked_stencil = spe_allocate_available_register(f); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_compare_greater_uint(f, stencil_pass_reg, tmp_masked_stencil, - state->valuemask & state->ref_value); + state->valuemask & ref_value); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_masked_stencil); } @@ -1289,7 +1290,7 @@ gen_stencil_test(struct spe_function *f, * = fragment_mask & ~(reference > s) */ /* As above, we have to do this by loading a register */ int tmp_reg = spe_allocate_available_register(f); - spe_load_uint(f, tmp_reg, state->ref_value); + spe_load_uint(f, tmp_reg, ref_value); spe_clgt(f, stencil_pass_reg, tmp_reg, fbS_reg); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); spe_release_register(f, tmp_reg); @@ -1298,7 +1299,7 @@ gen_stencil_test(struct spe_function *f, /* stencil_pass = fragment_mask & ~((reference&mask) > (s&mask)) */ int tmp_reg = spe_allocate_available_register(f); int tmp_masked_stencil = spe_allocate_available_register(f); - spe_load_uint(f, tmp_reg, state->ref_value & state->valuemask); + spe_load_uint(f, tmp_reg, ref_value & state->valuemask); spe_and_uint(f, tmp_masked_stencil, fbS_reg, state->valuemask); spe_clgt(f, stencil_pass_reg, tmp_reg, tmp_masked_stencil); spe_andc(f, stencil_pass_reg, fragment_mask_reg, stencil_pass_reg); @@ -1453,6 +1454,7 @@ gen_stencil_values(struct spe_function *f, static void gen_get_stencil_values(struct spe_function *f, const struct pipe_stencil_state *stencil, + const unsigned ref_value, const uint depth_enabled, int fbS_reg, int *fail_reg, @@ -1488,7 +1490,7 @@ gen_get_stencil_values(struct spe_function *f, } else { *fail_reg = spe_allocate_available_register(f); - gen_stencil_values(f, stencil->fail_op, stencil->ref_value, + gen_stencil_values(f, stencil->fail_op, ref_value, 0xff, fbS_reg, *fail_reg); } @@ -1501,7 +1503,7 @@ gen_get_stencil_values(struct spe_function *f, } else { *zfail_reg = spe_allocate_available_register(f); - gen_stencil_values(f, stencil->zfail_op, stencil->ref_value, + gen_stencil_values(f, stencil->zfail_op, ref_value, 0xff, fbS_reg, *zfail_reg); } @@ -1516,7 +1518,7 @@ gen_get_stencil_values(struct spe_function *f, } else { *zpass_reg = spe_allocate_available_register(f); - gen_stencil_values(f, stencil->zpass_op, stencil->ref_value, + gen_stencil_values(f, stencil->zpass_op, ref_value, 0xff, fbS_reg, *zpass_reg); } } @@ -1528,7 +1530,8 @@ gen_get_stencil_values(struct spe_function *f, */ static boolean gen_stencil_depth_test(struct spe_function *f, - const struct pipe_depth_stencil_alpha_state *dsa, + const struct pipe_depth_stencil_alpha_state *dsa, + const struct pipe_stencil_ref *stencil_ref, const uint facing, const int mask_reg, const int fragZ_reg, const int fbZ_reg, const int fbS_reg) @@ -1551,6 +1554,7 @@ gen_stencil_depth_test(struct spe_function *f, int stencil_writemask_reg; int zmask_reg; int newS_reg; + unsigned ref_value; /* Stenciling is quite complex: up to six different configurable stencil * operations/calculations can be required (three each for front-facing @@ -1579,9 +1583,11 @@ gen_stencil_depth_test(struct spe_function *f, */ if (facing == CELL_FACING_BACK && dsa->stencil[1].enabled) { stencil = &dsa->stencil[1]; + ref_value = stencil_ref->ref_value[1]; } else { stencil = &dsa->stencil[0]; + ref_value = stencil_ref->ref_value[0]; } /* Calculate the writemask. If the writemask is trivial (either @@ -1641,7 +1647,7 @@ gen_stencil_depth_test(struct spe_function *f, */ spe_comment(f, 0, "Running basic stencil test"); stencil_pass_reg = spe_allocate_available_register(f); - gen_stencil_test(f, stencil, 0xff, mask_reg, fbS_reg, stencil_pass_reg); + gen_stencil_test(f, stencil, ref_value, 0xff, mask_reg, fbS_reg, stencil_pass_reg); /* Generate code that, given the mask of valid fragments and the * mask of valid fragments that passed the stencil test, computes @@ -1678,7 +1684,7 @@ gen_stencil_depth_test(struct spe_function *f, spe_comment(f, 0, facing == CELL_FACING_FRONT ? "Computing front-facing stencil values" : "Computing back-facing stencil values"); - gen_get_stencil_values(f, stencil, dsa->depth.enabled, fbS_reg, + gen_get_stencil_values(f, stencil, ref_value, dsa->depth.enabled, fbS_reg, &stencil_fail_values, &stencil_pass_depth_fail_values, &stencil_pass_depth_pass_values); } @@ -1818,6 +1824,7 @@ gen_stencil_depth_test(struct spe_function *f, static void gen_depth_stencil(struct cell_context *cell, const struct pipe_depth_stencil_alpha_state *dsa, + const struct pipe_stencil_ref *stencil_ref, struct spe_function *f, uint facing, int mask_reg, @@ -1940,7 +1947,7 @@ gen_depth_stencil(struct cell_context *cell, * gen_stencil_depth_test() function must ignore the * fbZ_reg register if depth is not enabled. */ - write_depth_stencil = gen_stencil_depth_test(f, dsa, facing, + write_depth_stencil = gen_stencil_depth_test(f, dsa, stencil_ref, facing, mask_reg, fragZ_reg, fbZ_reg, fbS_reg); } @@ -2029,6 +2036,7 @@ cell_gen_fragment_function(struct cell_context *cell, struct spe_function *f) { const struct pipe_depth_stencil_alpha_state *dsa = cell->depth_stencil; + const struct pipe_stencil_ref *stencil_ref = &cell->stencil_ref; const struct pipe_blend_state *blend = cell->blend; const struct pipe_blend_color *blend_color = &cell->blend_color; const enum pipe_format color_format = cell->framebuffer.cbufs[0]->format; @@ -2101,7 +2109,7 @@ cell_gen_fragment_function(struct cell_context *cell, /* generate depth and/or stencil test code */ if (dsa->depth.enabled || dsa->stencil[0].enabled) { - gen_depth_stencil(cell, dsa, f, + gen_depth_stencil(cell, dsa, stencil_ref, f, facing, mask_reg, depth_tile_reg, diff --git a/src/gallium/drivers/cell/ppu/cell_pipe_state.c b/src/gallium/drivers/cell/ppu/cell_pipe_state.c index 3259c58687..3d8b4409c7 100644 --- a/src/gallium/drivers/cell/ppu/cell_pipe_state.c +++ b/src/gallium/drivers/cell/ppu/cell_pipe_state.c @@ -113,6 +113,19 @@ cell_delete_depth_stencil_alpha_state(struct pipe_context *pipe, void *dsa) static void +cell_set_stencil_ref(struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref) +{ + struct cell_context *cell = cell_context(pipe); + + draw_flush(cell->draw); + + cell->stencil_ref = *stencil_ref; + + cell->dirty |= CELL_NEW_DEPTH_STENCIL; +} + +static void cell_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) { @@ -397,6 +410,7 @@ cell_init_state_functions(struct cell_context *cell) cell->pipe.delete_rasterizer_state = cell_delete_rasterizer_state; cell->pipe.set_blend_color = cell_set_blend_color; + cell->pipe.set_stencil_ref = cell_set_stencil_ref; cell->pipe.set_clip_state = cell_set_clip_state; cell->pipe.set_framebuffer_state = cell_set_framebuffer_state; diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c index 7681e3411e..449855f539 100644 --- a/src/gallium/drivers/cell/ppu/cell_screen.c +++ b/src/gallium/drivers/cell/ppu/cell_screen.c @@ -33,6 +33,7 @@ #include "pipe/p_screen.h" #include "cell/common.h" +#include "cell_context.h" #include "cell_screen.h" #include "cell_texture.h" #include "cell_winsys.h" @@ -58,6 +59,8 @@ cell_get_param(struct pipe_screen *screen, int param) switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: return CELL_MAX_SAMPLERS; + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return CELL_MAX_SAMPLERS; case PIPE_CAP_NPOT_TEXTURES: return 1; case PIPE_CAP_TWO_SIDED_STENCIL: diff --git a/src/gallium/drivers/cell/ppu/cell_state_emit.c b/src/gallium/drivers/cell/ppu/cell_state_emit.c index 282f05ba08..a59c7828ac 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_emit.c +++ b/src/gallium/drivers/cell/ppu/cell_state_emit.c @@ -28,6 +28,7 @@ #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_math.h" +#include "util/u_format.h" #include "cell_context.h" #include "cell_gen_fragment.h" #include "cell_state.h" @@ -207,8 +208,8 @@ cell_emit_state(struct cell_context *cell) fb->width = cell->framebuffer.width; fb->height = cell->framebuffer.height; #if 0 - printf("EMIT color format %s\n", pf_name(fb->color_format)); - printf("EMIT depth format %s\n", pf_name(fb->depth_format)); + printf("EMIT color format %s\n", util_format_name(fb->color_format)); + printf("EMIT depth format %s\n", util_format_name(fb->depth_format)); #endif } diff --git a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c index 21af7ed1c3..07be5e92ea 100644 --- a/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c +++ b/src/gallium/drivers/cell/ppu/cell_state_per_fragment.c @@ -282,6 +282,7 @@ emit_stencil_op(struct spe_function *f, */ static int emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, + struct pipe_stencil_ref *sr, unsigned face, struct spe_function *f, int mask, @@ -296,7 +297,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, int stencil_pass = spe_allocate_available_register(f); int face_stencil = spe_allocate_available_register(f); int stencil_src = stencil; - const unsigned ref = (dsa->stencil[face].ref_value + const unsigned ref = (sr->ref_value[face] & dsa->stencil[face].valuemask); boolean complement = FALSE; int stored; @@ -406,7 +407,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, emit_stencil_op(f, face_stencil, stencil_src, stencil_fail, dsa->stencil[face].fail_op, - dsa->stencil[face].ref_value); + sr->ref_value[face]); stencil_src = face_stencil; } @@ -421,7 +422,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, emit_stencil_op(f, face_stencil, stencil_src, depth_fail, dsa->stencil[face].zfail_op, - dsa->stencil[face].ref_value); + sr->ref_value[face]); stencil_src = face_stencil; } @@ -429,7 +430,7 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, && (dsa->stencil[face].zpass_op != PIPE_STENCIL_OP_KEEP)) { emit_stencil_op(f, face_stencil, stencil_src, depth_pass, dsa->stencil[face].zpass_op, - dsa->stencil[face].ref_value); + sr->ref_value[face]); stencil_src = face_stencil; } } @@ -463,7 +464,8 @@ emit_stencil_test(struct pipe_depth_stencil_alpha_state *dsa, void -cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) +cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa, + struct pipe_stencil_ref *sr) { struct pipe_depth_stencil_alpha_state *const dsa = &cdsa->base; struct spe_function *const f = &cdsa->code; @@ -499,13 +501,13 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) if (dsa->stencil[0].enabled) { const int front_depth_pass = spe_allocate_available_register(f); - int front_stencil = emit_stencil_test(dsa, 0, f, mask, + int front_stencil = emit_stencil_test(dsa, sr, 0, f, mask, depth_mask, depth_complement, stencil, front_depth_pass); if (dsa->stencil[1].enabled) { const int back_depth_pass = spe_allocate_available_register(f); - int back_stencil = emit_stencil_test(dsa, 1, f, mask, + int back_stencil = emit_stencil_test(dsa, sr, 1, f, mask, depth_mask, depth_complement, stencil, back_depth_pass); @@ -579,7 +581,7 @@ cell_generate_depth_stencil_test(struct cell_depth_stencil_alpha_state *cdsa) dsa->stencil[i].zfail_op, dsa->stencil[i].zpass_op); printf("# ref value / value mask / write mask: %02x %02x %02x\n", - dsa->stencil[i].ref_value, + sr->ref_value[i], dsa->stencil[i].valuemask, dsa->stencil[i].writemask); } diff --git a/src/gallium/drivers/failover/fo_context.h b/src/gallium/drivers/failover/fo_context.h index 191a44c3df..bb1a168ea7 100644 --- a/src/gallium/drivers/failover/fo_context.h +++ b/src/gallium/drivers/failover/fo_context.h @@ -51,9 +51,10 @@ #define FO_NEW_VERTEX 0x2000 #define FO_NEW_VERTEX_SHADER 0x4000 #define FO_NEW_BLEND_COLOR 0x8000 -#define FO_NEW_CLEAR_COLOR 0x10000 -#define FO_NEW_VERTEX_BUFFER 0x20000 -#define FO_NEW_VERTEX_ELEMENT 0x40000 +#define FO_NEW_STENCIL_REF 0x10000 +#define FO_NEW_CLEAR_COLOR 0x20000 +#define FO_NEW_VERTEX_BUFFER 0x40000 +#define FO_NEW_VERTEX_ELEMENT 0x80000 @@ -79,6 +80,7 @@ struct failover_context { const struct fo_state *vertex_shader; struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; struct pipe_framebuffer_state framebuffer; struct pipe_poly_stipple poly_stipple; diff --git a/src/gallium/drivers/failover/fo_state.c b/src/gallium/drivers/failover/fo_state.c index c189d1d82c..970606a3f5 100644 --- a/src/gallium/drivers/failover/fo_state.c +++ b/src/gallium/drivers/failover/fo_state.c @@ -90,7 +90,7 @@ failover_delete_blend_state( struct pipe_context *pipe, static void failover_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ) + const struct pipe_blend_color *blend_color ) { struct failover_context *failover = failover_context(pipe); @@ -100,9 +100,21 @@ failover_set_blend_color( struct pipe_context *pipe, failover->hw->set_blend_color( failover->hw, blend_color ); } +static void +failover_set_stencil_ref( struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref ) +{ + struct failover_context *failover = failover_context(pipe); + + failover->stencil_ref = *stencil_ref; + failover->dirty |= FO_NEW_STENCIL_REF; + failover->sw->set_stencil_ref( failover->sw, stencil_ref ); + failover->hw->set_stencil_ref( failover->hw, stencil_ref ); +} + static void failover_set_clip_state( struct pipe_context *pipe, - const struct pipe_clip_state *clip ) + const struct pipe_clip_state *clip ) { struct failover_context *failover = failover_context(pipe); @@ -533,6 +545,7 @@ failover_init_state_functions( struct failover_context *failover ) failover->pipe.delete_vs_state = failover_delete_vs_state; failover->pipe.set_blend_color = failover_set_blend_color; + failover->pipe.set_stencil_ref = failover_set_stencil_ref; failover->pipe.set_clip_state = failover_set_clip_state; failover->pipe.set_framebuffer_state = failover_set_framebuffer_state; failover->pipe.set_polygon_stipple = failover_set_polygon_stipple; diff --git a/src/gallium/drivers/failover/fo_state_emit.c b/src/gallium/drivers/failover/fo_state_emit.c index a3341e33f8..5c00080842 100644 --- a/src/gallium/drivers/failover/fo_state_emit.c +++ b/src/gallium/drivers/failover/fo_state_emit.c @@ -65,7 +65,10 @@ failover_state_emit( struct failover_context *failover ) if (failover->dirty & FO_NEW_DEPTH_STENCIL) failover->sw->bind_depth_stencil_alpha_state( failover->sw, - failover->depth_stencil->sw_state ); + failover->depth_stencil->sw_state ); + + if (failover->dirty & FO_NEW_STENCIL_REF) + failover->sw->set_stencil_ref( failover->sw, &failover->stencil_ref ); if (failover->dirty & FO_NEW_FRAMEBUFFER) failover->sw->set_framebuffer_state( failover->sw, &failover->framebuffer ); diff --git a/src/gallium/drivers/i915/i915_context.h b/src/gallium/drivers/i915/i915_context.h index 1479d2201a..da769e7b29 100644 --- a/src/gallium/drivers/i915/i915_context.h +++ b/src/gallium/drivers/i915/i915_context.h @@ -232,6 +232,7 @@ struct i915_context struct i915_fragment_shader *fs; struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; /* XXX unneded */ struct pipe_buffer *constants[PIPE_SHADER_TYPES]; diff --git a/src/gallium/drivers/i915/i915_state.c b/src/gallium/drivers/i915/i915_state.c index beb26e996a..62169918e2 100644 --- a/src/gallium/drivers/i915/i915_state.c +++ b/src/gallium/drivers/i915/i915_state.c @@ -190,7 +190,7 @@ static void i915_delete_blend_state(struct pipe_context *pipe, void *blend) } static void i915_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ) + const struct pipe_blend_color *blend_color ) { struct i915_context *i915 = i915_context(pipe); draw_flush(i915->draw); @@ -200,6 +200,17 @@ static void i915_set_blend_color( struct pipe_context *pipe, i915->dirty |= I915_NEW_BLEND; } +static void i915_set_stencil_ref( struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref ) +{ + struct i915_context *i915 = i915_context(pipe); + draw_flush(i915->draw); + + i915->stencil_ref = *stencil_ref; + + i915->dirty |= I915_NEW_DEPTH_STENCIL; +} + static void * i915_create_sampler_state(struct pipe_context *pipe, const struct pipe_sampler_state *sampler) @@ -217,10 +228,10 @@ i915_create_sampler_state(struct pipe_context *pipe, minFilt = translate_img_filter( sampler->min_img_filter ); magFilt = translate_img_filter( sampler->mag_img_filter ); - if (sampler->max_anisotropy > 1.0) + if (sampler->max_anisotropy > 1) minFilt = magFilt = FILTER_ANISOTROPIC; - if (sampler->max_anisotropy > 2.0) { + if (sampler->max_anisotropy > 2) { cso->state[0] |= SS2_MAX_ANISO_4; } @@ -334,11 +345,9 @@ i915_create_depth_stencil_state(struct pipe_context *pipe, int fop = i915_translate_stencil_op(depth_stencil->stencil[0].fail_op); int dfop = i915_translate_stencil_op(depth_stencil->stencil[0].zfail_op); int dpop = i915_translate_stencil_op(depth_stencil->stencil[0].zpass_op); - int ref = depth_stencil->stencil[0].ref_value & 0xff; cso->stencil_LIS5 |= (S5_STENCIL_TEST_ENABLE | S5_STENCIL_WRITE_ENABLE | - (ref << S5_STENCIL_REF_SHIFT) | (test << S5_STENCIL_TEST_FUNC_SHIFT) | (fop << S5_STENCIL_FAIL_SHIFT) | (dfop << S5_STENCIL_PASS_Z_FAIL_SHIFT) | @@ -350,7 +359,6 @@ i915_create_depth_stencil_state(struct pipe_context *pipe, int fop = i915_translate_stencil_op(depth_stencil->stencil[1].fail_op); int dfop = i915_translate_stencil_op(depth_stencil->stencil[1].zfail_op); int dpop = i915_translate_stencil_op(depth_stencil->stencil[1].zpass_op); - int ref = depth_stencil->stencil[1].ref_value & 0xff; int tmask = depth_stencil->stencil[1].valuemask & 0xff; int wmask = depth_stencil->stencil[1].writemask & 0xff; @@ -359,7 +367,6 @@ i915_create_depth_stencil_state(struct pipe_context *pipe, BFO_ENABLE_STENCIL_TWO_SIDE | BFO_ENABLE_STENCIL_REF | BFO_STENCIL_TWO_SIDE | - (ref << BFO_STENCIL_REF_SHIFT) | (test << BFO_STENCIL_TEST_SHIFT) | (fop << BFO_STENCIL_FAIL_SHIFT) | (dfop << BFO_STENCIL_PASS_Z_FAIL_SHIFT) | @@ -777,6 +784,7 @@ i915_init_state_functions( struct i915_context *i915 ) i915->base.delete_vs_state = i915_delete_vs_state; i915->base.set_blend_color = i915_set_blend_color; + i915->base.set_stencil_ref = i915_set_stencil_ref; i915->base.set_clip_state = i915_set_clip_state; i915->base.set_constant_buffer = i915_set_constant_buffer; i915->base.set_framebuffer_state = i915_set_framebuffer_state; diff --git a/src/gallium/drivers/i915/i915_state_dynamic.c b/src/gallium/drivers/i915/i915_state_dynamic.c index 86126a5a15..9c6723b391 100644 --- a/src/gallium/drivers/i915/i915_state_dynamic.c +++ b/src/gallium/drivers/i915/i915_state_dynamic.c @@ -94,9 +94,16 @@ const struct i915_tracked_state i915_upload_MODES4 = { static void upload_BFO( struct i915_context *i915 ) { + unsigned bfo[2]; + bfo[0] = i915->depth_stencil->bfo[0]; + bfo[1] = i915->depth_stencil->bfo[1]; + /* I don't get it only allowed to set a ref mask when the enable bit is set? */ + if (bfo[0] & BFO_ENABLE_STENCIL_REF) { + bfo[0] |= i915->stencil_ref.ref_value[1] << BFO_STENCIL_REF_SHIFT; + } set_dynamic_indirect( i915, I915_DYNAMIC_BFO_0, - &(i915->depth_stencil->bfo[0]), + &(bfo[0]), 2 ); } diff --git a/src/gallium/drivers/i915/i915_state_immediate.c b/src/gallium/drivers/i915/i915_state_immediate.c index 8c16bb4e27..d2c6f15143 100644 --- a/src/gallium/drivers/i915/i915_state_immediate.c +++ b/src/gallium/drivers/i915/i915_state_immediate.c @@ -129,6 +129,8 @@ static void upload_S5( struct i915_context *i915 ) unsigned LIS5 = 0; LIS5 |= i915->depth_stencil->stencil_LIS5; + /* hope it's safe to set stencil ref value even if stencil test is disabled? */ + LIS5 |= i915->stencil_ref.ref_value[0] << S5_STENCIL_REF_SHIFT; LIS5 |= i915->blend->LIS5; diff --git a/src/gallium/drivers/i965/brw_cc.c b/src/gallium/drivers/i965/brw_cc.c index 4a543276f5..cc8e380c68 100644 --- a/src/gallium/drivers/i965/brw_cc.c +++ b/src/gallium/drivers/i965/brw_cc.c @@ -65,14 +65,33 @@ combine_cc3( struct brw_cc3 a, struct brw_cc3 b ) return ca.cc3; } +static INLINE struct brw_cc1 +combine_cc1( struct brw_cc1 a, struct brw_cc1 b ) +{ + union { struct brw_cc1 cc1; unsigned i; } ca, cb; + ca.cc1 = a; + cb.cc1 = b; + ca.i |= cb.i; + return ca.cc1; +} + +static INLINE struct brw_cc2 +combine_cc2( struct brw_cc2 a, struct brw_cc2 b ) +{ + union { struct brw_cc2 cc2; unsigned i; } ca, cb; + ca.cc2 = a; + cb.cc2 = b; + ca.i |= cb.i; + return ca.cc2; +} static int prepare_cc_unit( struct brw_context *brw ) { brw->cc.cc.cc0 = brw->curr.zstencil->cc0; - brw->cc.cc.cc1 = brw->curr.zstencil->cc1; - brw->cc.cc.cc2 = brw->curr.zstencil->cc2; + brw->cc.cc.cc1 = combine_cc1( brw->curr.zstencil->cc1, brw->curr.cc1_stencil_ref ); + brw->cc.cc.cc2 = combine_cc2( brw->curr.zstencil->cc2, brw->curr.blend->cc2 ); brw->cc.cc.cc3 = combine_cc3( brw->curr.zstencil->cc3, brw->curr.blend->cc3 ); - + brw->cc.cc.cc5 = brw->curr.blend->cc5; brw->cc.cc.cc6 = brw->curr.blend->cc6; brw->cc.cc.cc7 = brw->curr.zstencil->cc7; diff --git a/src/gallium/drivers/i965/brw_context.h b/src/gallium/drivers/i965/brw_context.h index 19fda423de..12cfa7b049 100644 --- a/src/gallium/drivers/i965/brw_context.h +++ b/src/gallium/drivers/i965/brw_context.h @@ -153,7 +153,6 @@ struct brw_blend_state { struct brw_surf_ss0 ss0; }; - struct brw_rasterizer_state; struct brw_immediate_data { @@ -560,12 +559,14 @@ struct brw_context struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; + struct pipe_stencil_ref stencil_ref; struct pipe_framebuffer_state fb; struct pipe_clip_state ucp; struct pipe_buffer *vertex_constants; struct pipe_buffer *fragment_constants; struct brw_blend_constant_color bcc; + struct brw_cc1 cc1_stencil_ref; struct brw_polygon_stipple bps; struct brw_cc_viewport ccv; diff --git a/src/gallium/drivers/i965/brw_pipe_depth.c b/src/gallium/drivers/i965/brw_pipe_depth.c index e010d76e0d..b7000d5e33 100644 --- a/src/gallium/drivers/i965/brw_pipe_depth.c +++ b/src/gallium/drivers/i965/brw_pipe_depth.c @@ -72,7 +72,6 @@ static void create_bcc_state( struct brw_depth_stencil_state *zstencil, translate_stencil_op(templ->stencil[0].zfail_op); zstencil->cc0.stencil_pass_depth_pass_op = translate_stencil_op(templ->stencil[0].zpass_op); - zstencil->cc1.stencil_ref = templ->stencil[0].ref_value; zstencil->cc1.stencil_write_mask = templ->stencil[0].writemask; zstencil->cc1.stencil_test_mask = templ->stencil[0].valuemask; @@ -86,7 +85,6 @@ static void create_bcc_state( struct brw_depth_stencil_state *zstencil, translate_stencil_op(templ->stencil[1].zfail_op); zstencil->cc0.bf_stencil_pass_depth_pass_op = translate_stencil_op(templ->stencil[1].zpass_op); - zstencil->cc1.bf_stencil_ref = templ->stencil[1].ref_value; zstencil->cc2.bf_stencil_write_mask = templ->stencil[1].writemask; zstencil->cc2.bf_stencil_test_mask = templ->stencil[1].valuemask; } @@ -159,9 +157,19 @@ static void brw_delete_depth_stencil_state(struct pipe_context *pipe, FREE(cso); } +static void brw_set_stencil_ref(struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref) +{ + struct brw_context *brw = brw_context(pipe); + brw->curr.cc1_stencil_ref.stencil_ref = stencil_ref->ref_value[0]; + brw->curr.cc1_stencil_ref.bf_stencil_ref = stencil_ref->ref_value[1]; + + brw->state.dirty.mesa |= PIPE_NEW_DEPTH_STENCIL_ALPHA; +} void brw_pipe_depth_stencil_init( struct brw_context *brw ) { + brw->base.set_stencil_ref = brw_set_stencil_ref; brw->base.create_depth_stencil_alpha_state = brw_create_depth_stencil_state; brw->base.bind_depth_stencil_alpha_state = brw_bind_depth_stencil_state; brw->base.delete_depth_stencil_alpha_state = brw_delete_depth_stencil_state; diff --git a/src/gallium/drivers/i965/brw_pipe_sampler.c b/src/gallium/drivers/i965/brw_pipe_sampler.c index 6aab561004..c7c0e2ae95 100644 --- a/src/gallium/drivers/i965/brw_pipe_sampler.c +++ b/src/gallium/drivers/i965/brw_pipe_sampler.c @@ -114,14 +114,12 @@ brw_create_sampler_state( struct pipe_context *pipe, /* XXX: anisotropy logic slightly changed: */ - if (template->max_anisotropy > 1.0) { + if (template->max_anisotropy > 1) { sampler->ss0.min_filter = BRW_MAPFILTER_ANISOTROPIC; sampler->ss0.mag_filter = BRW_MAPFILTER_ANISOTROPIC; - if (template->max_anisotropy > 2.0) { - sampler->ss3.max_aniso = MIN2((template->max_anisotropy - 2) / 2, - BRW_ANISORATIO_16); - } + sampler->ss3.max_aniso = MIN2((template->max_anisotropy - 2) / 2, + BRW_ANISORATIO_16); } sampler->ss1.r_wrap_mode = translate_wrap_mode(template->wrap_r); diff --git a/src/gallium/drivers/identity/id_context.c b/src/gallium/drivers/identity/id_context.c index 9955380e1f..8248b2a413 100644 --- a/src/gallium/drivers/identity/id_context.c +++ b/src/gallium/drivers/identity/id_context.c @@ -389,6 +389,17 @@ identity_set_blend_color(struct pipe_context *_pipe, } static void +identity_set_stencil_ref(struct pipe_context *_pipe, + const struct pipe_stencil_ref *stencil_ref) +{ + struct identity_context *id_pipe = identity_context(_pipe); + struct pipe_context *pipe = id_pipe->pipe; + + pipe->set_stencil_ref(pipe, + stencil_ref); +} + +static void identity_set_clip_state(struct pipe_context *_pipe, const struct pipe_clip_state *clip) { @@ -723,6 +734,7 @@ identity_context_create(struct pipe_screen *_screen, struct pipe_context *pipe) id_pipe->base.bind_vs_state = identity_bind_vs_state; id_pipe->base.delete_vs_state = identity_delete_vs_state; id_pipe->base.set_blend_color = identity_set_blend_color; + id_pipe->base.set_stencil_ref = identity_set_stencil_ref; id_pipe->base.set_clip_state = identity_set_clip_state; id_pipe->base.set_constant_buffer = identity_set_constant_buffer; id_pipe->base.set_framebuffer_state = identity_set_framebuffer_state; diff --git a/src/gallium/drivers/llvmpipe/lp_context.c b/src/gallium/drivers/llvmpipe/lp_context.c index eded68bbc3..9120226de0 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.c +++ b/src/gallium/drivers/llvmpipe/lp_context.c @@ -146,6 +146,7 @@ llvmpipe_create_context( struct pipe_screen *screen, void *priv ) llvmpipe->pipe.delete_vs_state = llvmpipe_delete_vs_state; llvmpipe->pipe.set_blend_color = llvmpipe_set_blend_color; + llvmpipe->pipe.set_stencil_ref = llvmpipe_set_stencil_ref; llvmpipe->pipe.set_clip_state = llvmpipe_set_clip_state; llvmpipe->pipe.set_constant_buffer = llvmpipe_set_constant_buffer; llvmpipe->pipe.set_framebuffer_state = llvmpipe_set_framebuffer_state; diff --git a/src/gallium/drivers/llvmpipe/lp_context.h b/src/gallium/drivers/llvmpipe/lp_context.h index 3bde485ac0..955c7eb8e0 100644 --- a/src/gallium/drivers/llvmpipe/lp_context.h +++ b/src/gallium/drivers/llvmpipe/lp_context.h @@ -61,6 +61,7 @@ struct llvmpipe_context { /** Other rendering state */ struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; struct pipe_buffer *constants[PIPE_SHADER_TYPES]; struct pipe_framebuffer_state framebuffer; diff --git a/src/gallium/drivers/llvmpipe/lp_rast_tri.c b/src/gallium/drivers/llvmpipe/lp_rast_tri.c index 3f76f159df..0334705ef7 100644 --- a/src/gallium/drivers/llvmpipe/lp_rast_tri.c +++ b/src/gallium/drivers/llvmpipe/lp_rast_tri.c @@ -146,42 +146,55 @@ static void do_block_16( struct lp_rasterizer_task *rast_task, const struct lp_rast_triangle *tri, int x, int y, + int c0, int c1, - int c2, - int c3 ) + int c2 ) { - const int eo1 = tri->eo1 * 4; - const int eo2 = tri->eo2 * 4; - const int eo3 = tri->eo3 * 4; - const int *step0 = tri->inputs.step[0]; - const int *step1 = tri->inputs.step[1]; - const int *step2 = tri->inputs.step[2]; - int i; + unsigned mask = 0; + int eo[3]; + int c[3]; + int i, j; assert(x % 16 == 0); assert(y % 16 == 0); - for (i = 0; i < 16; i++) { - int cx1 = c1 + step0[i] * 4; - int cx2 = c2 + step1[i] * 4; - int cx3 = c3 + step2[i] * 4; + eo[0] = tri->eo1 * 4; + eo[1] = tri->eo2 * 4; + eo[2] = tri->eo3 * 4; - if (cx1 + eo1 < 0 || - cx2 + eo2 < 0 || - cx3 + eo3 < 0) { - /* the block is completely outside the triangle - nop */ - LP_COUNT(nr_empty_4); - } - else { - int px = x + pos_table4[i][0]; - int py = y + pos_table4[i][1]; - /* Don't bother testing if the 4x4 block is entirely in/out of - * the triangle. It's a little faster to do it in the jit code. - */ - LP_COUNT(nr_non_empty_4); - do_block_4(rast_task, tri, px, py, cx1, cx2, cx3); + c[0] = c0; + c[1] = c1; + c[2] = c2; + + for (j = 0; j < 3; j++) { + const int *step = tri->inputs.step[j]; + const int cx = c[j] + eo[j]; + + /* Mask has bits set whenever we are outside any of the edges. + */ + for (i = 0; i < 16; i++) { + int out = cx + step[i] * 4; + mask |= (out >> 31) & (1 << i); } } + + mask = ~mask & 0xffff; + while (mask) { + int i = ffs(mask) - 1; + int px = x + pos_table4[i][0]; + int py = y + pos_table4[i][1]; + int cx1 = c0 + tri->inputs.step[0][i] * 4; + int cx2 = c1 + tri->inputs.step[1][i] * 4; + int cx3 = c2 + tri->inputs.step[2][i] * 4; + + mask &= ~(1 << i); + + /* Don't bother testing if the 4x4 block is entirely in/out of + * the triangle. It's a little faster to do it in the jit code. + */ + LP_COUNT(nr_non_empty_4); + do_block_4(rast_task, tri, px, py, cx1, cx2, cx3); + } } @@ -199,53 +212,79 @@ lp_rast_triangle( struct lp_rasterizer *rast, int x = rast_task->x; int y = rast_task->y; - unsigned i; + int ei[3], eo[3], c[3]; + unsigned outmask, inmask, partial_mask; + unsigned i, j; - int c1 = tri->c1 + tri->dx12 * y - tri->dy12 * x; - int c2 = tri->c2 + tri->dx23 * y - tri->dy23 * x; - int c3 = tri->c3 + tri->dx31 * y - tri->dy31 * x; + c[0] = tri->c1 + tri->dx12 * y - tri->dy12 * x; + c[1] = tri->c2 + tri->dx23 * y - tri->dy23 * x; + c[2] = tri->c3 + tri->dx31 * y - tri->dy31 * x; - int ei1 = tri->ei1 * 16; - int ei2 = tri->ei2 * 16; - int ei3 = tri->ei3 * 16; + eo[0] = tri->eo1 * 16; + eo[1] = tri->eo2 * 16; + eo[2] = tri->eo3 * 16; - int eo1 = tri->eo1 * 16; - int eo2 = tri->eo2 * 16; - int eo3 = tri->eo3 * 16; + ei[0] = tri->ei1 * 16; + ei[1] = tri->ei2 * 16; + ei[2] = tri->ei3 * 16; - LP_DBG(DEBUG_RAST, "lp_rast_triangle\n"); + outmask = 0; + inmask = 0xffff; - /* Walk over the tile to build a list of 4x4 pixel blocks which will - * be filled/shaded. We do this at two granularities: 16x16 blocks - * and then 4x4 blocks. - */ - for (i = 0; i < 16; i++) { - int cx1 = c1 + (tri->inputs.step[0][i] * 16); - int cx2 = c2 + (tri->inputs.step[1][i] * 16); - int cx3 = c3 + (tri->inputs.step[2][i] * 16); - - if (cx1 + eo1 < 0 || - cx2 + eo2 < 0 || - cx3 + eo3 < 0) { - /* the block is completely outside the triangle - nop */ - LP_COUNT(nr_empty_16); - } - else { - int px = x + pos_table16[i][0]; - int py = y + pos_table16[i][1]; - - if (cx1 + ei1 > 0 && - cx2 + ei2 > 0 && - cx3 + ei3 > 0) { - /* the block is completely inside the triangle */ - LP_COUNT(nr_fully_covered_16); - block_full_16(rast_task, tri, px, py); - } - else { - /* the block is partially in/out of the triangle */ - LP_COUNT(nr_partially_covered_16); - do_block_16(rast_task, tri, px, py, cx1, cx2, cx3); - } + for (j = 0; j < 3; j++) { + const int *step = tri->inputs.step[j]; + const int cox = c[j] + eo[j]; + const int cio = ei[j]- eo[j]; + + /* Outmask has bits set whenever we are outside any of the + * edges. + */ + /* Inmask has bits set whenever we are inside all of the edges. + */ + for (i = 0; i < 16; i++) { + int out = cox + step[i] * 16; + int in = out + cio; + outmask |= (out >> 31) & (1 << i); + inmask &= ~((in >> 31) & (1 << i)); } } + + assert((outmask & inmask) == 0); + + if (outmask == 0xffff) + return; + + /* Invert mask, so that bits are set whenever we are at least + * partially inside all of the edges: + */ + partial_mask = ~inmask & ~outmask & 0xffff; + + /* Iterate over partials: + */ + while (partial_mask) { + int i = ffs(partial_mask) - 1; + int px = x + pos_table16[i][0]; + int py = y + pos_table16[i][1]; + int cx1 = c[0] + tri->inputs.step[0][i] * 16; + int cx2 = c[1] + tri->inputs.step[1][i] * 16; + int cx3 = c[2] + tri->inputs.step[2][i] * 16; + + partial_mask &= ~(1 << i); + + LP_COUNT(nr_partially_covered_16); + do_block_16(rast_task, tri, px, py, cx1, cx2, cx3); + } + + /* Iterate over fulls: + */ + while (inmask) { + int i = ffs(inmask) - 1; + int px = x + pos_table16[i][0]; + int py = y + pos_table16[i][1]; + + inmask &= ~(1 << i); + + LP_COUNT(nr_fully_covered_16); + block_full_16(rast_task, tri, px, py); + } } diff --git a/src/gallium/drivers/llvmpipe/lp_scene_queue.c b/src/gallium/drivers/llvmpipe/lp_scene_queue.c index 43d74e4d89..975db43c4e 100644 --- a/src/gallium/drivers/llvmpipe/lp_scene_queue.c +++ b/src/gallium/drivers/llvmpipe/lp_scene_queue.c @@ -92,6 +92,8 @@ lp_scene_dequeue(struct lp_scene_queue *queue, boolean wait) struct scene_packet packet; enum pipe_error ret; + packet.scene = NULL; + ret = util_ringbuffer_dequeue(queue->ring, &packet.header, sizeof packet / 4, diff --git a/src/gallium/drivers/llvmpipe/lp_setup.c b/src/gallium/drivers/llvmpipe/lp_setup.c index 538492beba..cb873667a2 100644 --- a/src/gallium/drivers/llvmpipe/lp_setup.c +++ b/src/gallium/drivers/llvmpipe/lp_setup.c @@ -251,6 +251,7 @@ lp_setup_bind_framebuffer( struct setup_context *setup, set_scene_state( setup, SETUP_FLUSHED ); /* re-get scene pointer, may have a new scene after flushing */ + (void) scene; scene = lp_setup_get_current_scene(setup); util_copy_framebuffer_state(&setup->fb, fb); diff --git a/src/gallium/drivers/llvmpipe/lp_state.h b/src/gallium/drivers/llvmpipe/lp_state.h index 8f68f12bed..9beba32271 100644 --- a/src/gallium/drivers/llvmpipe/lp_state.h +++ b/src/gallium/drivers/llvmpipe/lp_state.h @@ -152,13 +152,16 @@ void llvmpipe_bind_rasterizer_state(struct pipe_context *, void *); void llvmpipe_delete_rasterizer_state(struct pipe_context *, void *); void llvmpipe_set_framebuffer_state( struct pipe_context *, - const struct pipe_framebuffer_state * ); + const struct pipe_framebuffer_state * ); void llvmpipe_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ); +void llvmpipe_set_stencil_ref( struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref ); + void llvmpipe_set_clip_state( struct pipe_context *, - const struct pipe_clip_state * ); + const struct pipe_clip_state * ); void llvmpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, diff --git a/src/gallium/drivers/llvmpipe/lp_state_blend.c b/src/gallium/drivers/llvmpipe/lp_state_blend.c index 9b950e82d8..4ee28473e8 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_state_blend.c @@ -33,7 +33,7 @@ #include "util/u_memory.h" #include "util/u_math.h" -#include "util/u_debug_dump.h" +#include "util/u_dump.h" #include "draw/draw_context.h" #include "lp_screen.h" #include "lp_context.h" @@ -121,3 +121,24 @@ llvmpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth) { FREE( depth ); } + +void llvmpipe_set_stencil_ref( struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref ) +{ + struct llvmpipe_context *llvmpipe = llvmpipe_context(pipe); + + if(!stencil_ref) + return; + + if(memcmp(&llvmpipe->stencil_ref, stencil_ref, sizeof *stencil_ref) == 0) + return; + + draw_flush(llvmpipe->draw); + + memcpy(&llvmpipe->stencil_ref, stencil_ref, sizeof *stencil_ref); + + /* not sure. want new flag? */ + llvmpipe->dirty |= LP_NEW_DEPTH_STENCIL_ALPHA; +} + + diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c index 15c10d8e2e..90dae3f910 100644 --- a/src/gallium/drivers/llvmpipe/lp_state_fs.c +++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c @@ -65,7 +65,7 @@ #include "util/u_inlines.h" #include "util/u_memory.h" #include "util/u_format.h" -#include "util/u_debug_dump.h" +#include "util/u_dump.h" #include "os/os_time.h" #include "pipe/p_shader_tokens.h" #include "draw/draw_context.h" @@ -861,49 +861,49 @@ generate_variant(struct llvmpipe_context *lp, tgsi_dump(shader->base.tokens, 0); if(key->depth.enabled) { - debug_printf("depth.format = %s\n", pf_name(key->zsbuf_format)); - debug_printf("depth.func = %s\n", debug_dump_func(key->depth.func, TRUE)); + debug_printf("depth.format = %s\n", util_format_name(key->zsbuf_format)); + debug_printf("depth.func = %s\n", util_dump_func(key->depth.func, TRUE)); debug_printf("depth.writemask = %u\n", key->depth.writemask); } if(key->alpha.enabled) { - debug_printf("alpha.func = %s\n", debug_dump_func(key->alpha.func, TRUE)); + debug_printf("alpha.func = %s\n", util_dump_func(key->alpha.func, TRUE)); debug_printf("alpha.ref_value = %f\n", key->alpha.ref_value); } if(key->blend.logicop_enable) { debug_printf("blend.logicop_func = %u\n", key->blend.logicop_func); } else if(key->blend.rt[0].blend_enable) { - debug_printf("blend.rgb_func = %s\n", debug_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); - debug_printf("rgb_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); - debug_printf("rgb_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); - debug_printf("alpha_func = %s\n", debug_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); - debug_printf("alpha_src_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); - debug_printf("alpha_dst_factor = %s\n", debug_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); + debug_printf("blend.rgb_func = %s\n", util_dump_blend_func (key->blend.rt[0].rgb_func, TRUE)); + debug_printf("rgb_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE)); + debug_printf("rgb_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE)); + debug_printf("alpha_func = %s\n", util_dump_blend_func (key->blend.rt[0].alpha_func, TRUE)); + debug_printf("alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE)); + debug_printf("alpha_dst_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_dst_factor, TRUE)); } debug_printf("blend.colormask = 0x%x\n", key->blend.rt[0].colormask); for(i = 0; i < PIPE_MAX_SAMPLERS; ++i) { if(key->sampler[i].format) { debug_printf("sampler[%u] = \n", i); debug_printf(" .format = %s\n", - pf_name(key->sampler[i].format)); + util_format_name(key->sampler[i].format)); debug_printf(" .target = %s\n", - debug_dump_tex_target(key->sampler[i].target, TRUE)); + util_dump_tex_target(key->sampler[i].target, TRUE)); debug_printf(" .pot = %u %u %u\n", key->sampler[i].pot_width, key->sampler[i].pot_height, key->sampler[i].pot_depth); debug_printf(" .wrap = %s %s %s\n", - debug_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), - debug_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), - debug_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); + util_dump_tex_wrap(key->sampler[i].wrap_s, TRUE), + util_dump_tex_wrap(key->sampler[i].wrap_t, TRUE), + util_dump_tex_wrap(key->sampler[i].wrap_r, TRUE)); debug_printf(" .min_img_filter = %s\n", - debug_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); + util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE)); debug_printf(" .min_mip_filter = %s\n", - debug_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); + util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE)); debug_printf(" .mag_img_filter = %s\n", - debug_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); + util_dump_tex_filter(key->sampler[i].mag_img_filter, TRUE)); if(key->sampler[i].compare_mode != PIPE_TEX_COMPARE_NONE) - debug_printf(" .compare_func = %s\n", debug_dump_func(key->sampler[i].compare_func, TRUE)); + debug_printf(" .compare_func = %s\n", util_dump_func(key->sampler[i].compare_func, TRUE)); debug_printf(" .normalized_coords = %u\n", key->sampler[i].normalized_coords); } } diff --git a/src/gallium/drivers/llvmpipe/lp_test.h b/src/gallium/drivers/llvmpipe/lp_test.h index ca0f737b29..a9b99945f9 100644 --- a/src/gallium/drivers/llvmpipe/lp_test.h +++ b/src/gallium/drivers/llvmpipe/lp_test.h @@ -51,7 +51,7 @@ #include "pipe/p_state.h" #include "util/u_format.h" #include "util/u_math.h" -#include "util/u_debug_dump.h" +#include "util/u_dump.h" #include "gallivm/lp_bld_type.h" diff --git a/src/gallium/drivers/llvmpipe/lp_test_blend.c b/src/gallium/drivers/llvmpipe/lp_test_blend.c index e49b705598..5c9d418344 100644 --- a/src/gallium/drivers/llvmpipe/lp_test_blend.c +++ b/src/gallium/drivers/llvmpipe/lp_test_blend.c @@ -109,12 +109,12 @@ write_tsv_row(FILE *fp, fprintf(fp, "%s\t%s\t%s\t%s\t%s\t%s\n", - debug_dump_blend_func(blend->rt[0].rgb_func, TRUE), - debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE), - debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE), - debug_dump_blend_func(blend->rt[0].alpha_func, TRUE), - debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE), - debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE)); + util_dump_blend_func(blend->rt[0].rgb_func, TRUE), + util_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE), + util_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE), + util_dump_blend_func(blend->rt[0].alpha_func, TRUE), + util_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE), + util_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE)); fflush(fp); } @@ -136,12 +136,12 @@ dump_blend_type(FILE *fp, fprintf(fp, " %s=%s %s=%s %s=%s %s=%s %s=%s %s=%s", - "rgb_func", debug_dump_blend_func(blend->rt[0].rgb_func, TRUE), - "rgb_src_factor", debug_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE), - "rgb_dst_factor", debug_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE), - "alpha_func", debug_dump_blend_func(blend->rt[0].alpha_func, TRUE), - "alpha_src_factor", debug_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE), - "alpha_dst_factor", debug_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE)); + "rgb_func", util_dump_blend_func(blend->rt[0].rgb_func, TRUE), + "rgb_src_factor", util_dump_blend_factor(blend->rt[0].rgb_src_factor, TRUE), + "rgb_dst_factor", util_dump_blend_factor(blend->rt[0].rgb_dst_factor, TRUE), + "alpha_func", util_dump_blend_func(blend->rt[0].alpha_func, TRUE), + "alpha_src_factor", util_dump_blend_factor(blend->rt[0].alpha_src_factor, TRUE), + "alpha_dst_factor", util_dump_blend_factor(blend->rt[0].alpha_dst_factor, TRUE)); fprintf(fp, " ...\n"); fflush(fp); diff --git a/src/gallium/drivers/nouveau/nouveau_screen.c b/src/gallium/drivers/nouveau/nouveau_screen.c index 156cb2d229..81bc296ab4 100644 --- a/src/gallium/drivers/nouveau/nouveau_screen.c +++ b/src/gallium/drivers/nouveau/nouveau_screen.c @@ -55,7 +55,7 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, { struct nouveau_device *dev = nouveau_screen(pscreen)->device; struct nouveau_bo *bo = NULL; - uint32_t flags = NOUVEAU_BO_MAP; + uint32_t flags = NOUVEAU_BO_MAP, tile_mode = 0, tile_flags = 0; int ret; if (usage & NOUVEAU_BUFFER_USAGE_TRANSFER) @@ -77,13 +77,15 @@ nouveau_screen_bo_new(struct pipe_screen *pscreen, unsigned alignment, flags |= NOUVEAU_BO_VRAM; if (dev->chipset == 0x50 || dev->chipset >= 0x80) { - flags |= NOUVEAU_BO_TILED; if (usage & NOUVEAU_BUFFER_USAGE_ZETA) - flags |= NOUVEAU_BO_ZTILE; + tile_flags = 0x2800; + else + tile_flags = 0x7000; } } - ret = nouveau_bo_new(dev, flags, alignment, size, &bo); + ret = nouveau_bo_new_tile(dev, flags, alignment, size, + tile_mode, tile_flags, &bo); if (ret) return NULL; diff --git a/src/gallium/drivers/nouveau/nouveau_stateobj.h b/src/gallium/drivers/nouveau/nouveau_stateobj.h index e844f6abb3..5357e981de 100644 --- a/src/gallium/drivers/nouveau/nouveau_stateobj.h +++ b/src/gallium/drivers/nouveau/nouveau_stateobj.h @@ -229,7 +229,6 @@ so_bo_is_reloc(struct nouveau_stateobj *so, struct nouveau_bo *bo) static INLINE void so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so) { - struct nouveau_pushbuf *pb = chan->pushbuf; unsigned nr, i; int ret = 0; @@ -260,7 +259,7 @@ so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so) for (i = 0; i < so->cur_reloc; i++) { struct nouveau_stateobj_reloc *r = &so->reloc[i]; - if ((ret = nouveau_pushbuf_emit_reloc(chan, pb->cur - nr + + if ((ret = nouveau_pushbuf_emit_reloc(chan, chan->cur - nr + r->push_offset, r->bo, r->data, 0, r->flags, r->vor, r->tor))) { debug_printf("so_emit failed reloc with error %d\n", ret); @@ -272,7 +271,6 @@ so_emit(struct nouveau_channel *chan, struct nouveau_stateobj *so) static INLINE void so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so) { - struct nouveau_pushbuf *pb = chan->pushbuf; struct nouveau_grobj *gr = NULL; unsigned i; int ret = 0; @@ -318,8 +316,6 @@ so_emit_reloc_markers(struct nouveau_channel *chan, struct nouveau_stateobj *so) debug_printf("OUT_RELOC failed %d\n", ret); assert(0); } - - pb->remaining -= 2; } } diff --git a/src/gallium/drivers/nv30/nv30_context.h b/src/gallium/drivers/nv30/nv30_context.h index b3b26f7f94..ca3d6aca7f 100644 --- a/src/gallium/drivers/nv30/nv30_context.h +++ b/src/gallium/drivers/nv30/nv30_context.h @@ -61,7 +61,8 @@ enum nv30_state_index { NV30_STATE_VTXBUF = 31, NV30_STATE_VTXFMT = 32, NV30_STATE_VTXATTR = 33, - NV30_STATE_MAX = 34 + NV30_STATE_SR = 34, + NV30_STATE_MAX = 35 }; #include "nv30_screen.h" @@ -79,6 +80,7 @@ enum nv30_state_index { #define NV30_NEW_FRAGPROG (1 << 10) #define NV30_NEW_ARRAYS (1 << 11) #define NV30_NEW_UCP (1 << 12) +#define NV30_NEW_SR (1 << 13) struct nv30_rasterizer_state { struct pipe_rasterizer_state pipe; @@ -129,6 +131,7 @@ struct nv30_context { struct nv30_zsa_state *zsa; struct nv30_blend_state *blend; struct pipe_blend_color blend_colour; + struct pipe_stencil_ref stencil_ref; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; struct pipe_buffer *idxbuf; @@ -194,6 +197,7 @@ extern struct nv30_state_entry nv30_state_viewport; extern struct nv30_state_entry nv30_state_framebuffer; extern struct nv30_state_entry nv30_state_fragtex; extern struct nv30_state_entry nv30_state_vbo; +extern struct nv30_state_entry nv30_state_sr; /* nv30_vbo.c */ extern void nv30_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv30/nv30_fragtex.c b/src/gallium/drivers/nv30/nv30_fragtex.c index 0cc3172dcd..9f4a104f67 100644 --- a/src/gallium/drivers/nv30/nv30_fragtex.c +++ b/src/gallium/drivers/nv30/nv30_fragtex.c @@ -1,3 +1,5 @@ +#include "util/u_format.h" + #include "nv30_context.h" #include "nouveau/nouveau_util.h" @@ -50,7 +52,7 @@ nv30_fragtex_format(uint pipe_format) tf++; } - NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format)); + NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format)); return NULL; } diff --git a/src/gallium/drivers/nv30/nv30_screen.c b/src/gallium/drivers/nv30/nv30_screen.c index 8f9b26ea56..aef37d303d 100644 --- a/src/gallium/drivers/nv30/nv30_screen.c +++ b/src/gallium/drivers/nv30/nv30_screen.c @@ -28,7 +28,7 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) { switch (param) { case PIPE_CAP_MAX_TEXTURE_IMAGE_UNITS: - return 16; + return 8; case PIPE_CAP_NPOT_TEXTURES: return 0; case PIPE_CAP_TWO_SIDED_STENCIL: @@ -64,6 +64,8 @@ nv30_screen_get_param(struct pipe_screen *pscreen, int param) case NOUVEAU_CAP_HW_VTXBUF: case NOUVEAU_CAP_HW_IDXBUF: return 1; + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return 16; case PIPE_CAP_INDEP_BLEND_ENABLE: return 0; case PIPE_CAP_INDEP_BLEND_FUNC: diff --git a/src/gallium/drivers/nv30/nv30_state.c b/src/gallium/drivers/nv30/nv30_state.c index f775938ba7..d911c80707 100644 --- a/src/gallium/drivers/nv30/nv30_state.c +++ b/src/gallium/drivers/nv30/nv30_state.c @@ -139,13 +139,13 @@ nv30_sampler_state_create(struct pipe_context *pipe, ps->en = 0; - if (cso->max_anisotropy >= 8.0) { + if (cso->max_anisotropy >= 8) { ps->en |= NV34TCL_TX_ENABLE_ANISO_8X; } else - if (cso->max_anisotropy >= 4.0) { + if (cso->max_anisotropy >= 4) { ps->en |= NV34TCL_TX_ENABLE_ANISO_4X; } else - if (cso->max_anisotropy >= 2.0) { + if (cso->max_anisotropy >= 2) { ps->en |= NV34TCL_TX_ENABLE_ANISO_2X; } @@ -435,7 +435,7 @@ nv30_depth_stencil_alpha_state_create(struct pipe_context *pipe, { struct nv30_context *nv30 = nv30_context(pipe); struct nv30_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); - struct nouveau_stateobj *so = so_new(5, 21, 0); + struct nouveau_stateobj *so = so_new(6, 20, 0); struct nouveau_grobj *rankine = nv30->screen->rankine; so_method(so, rankine, NV34TCL_DEPTH_FUNC, 3); @@ -449,11 +449,11 @@ nv30_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, float_to_ubyte(cso->alpha.ref_value)); if (cso->stencil[0].enabled) { - so_method(so, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, rankine, NV34TCL_STENCIL_FRONT_ENABLE, 3); so_data (so, cso->stencil[0].enabled ? 1 : 0); so_data (so, cso->stencil[0].writemask); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); - so_data (so, cso->stencil[0].ref_value); + so_method(so, rankine, NV34TCL_STENCIL_FRONT_FUNC_MASK, 4); so_data (so, cso->stencil[0].valuemask); so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); @@ -464,11 +464,11 @@ nv30_depth_stencil_alpha_state_create(struct pipe_context *pipe, } if (cso->stencil[1].enabled) { - so_method(so, rankine, NV34TCL_STENCIL_BACK_ENABLE, 8); + so_method(so, rankine, NV34TCL_STENCIL_BACK_ENABLE, 3); so_data (so, cso->stencil[1].enabled ? 1 : 0); so_data (so, cso->stencil[1].writemask); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); - so_data (so, cso->stencil[1].ref_value); + so_method(so, rankine, NV34TCL_STENCIL_BACK_FUNC_MASK, 4); so_data (so, cso->stencil[1].valuemask); so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); @@ -583,6 +583,16 @@ nv30_set_blend_color(struct pipe_context *pipe, } static void +nv30_set_stencil_ref(struct pipe_context *pipe, + const struct pipe_stencil_ref *sr) +{ + struct nv30_context *nv30 = nv30_context(pipe); + + nv30->stencil_ref = *sr; + nv30->dirty |= NV30_NEW_SR; +} + +static void nv30_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) { @@ -704,6 +714,7 @@ nv30_init_state_functions(struct nv30_context *nv30) nv30->pipe.delete_fs_state = nv30_fp_state_delete; nv30->pipe.set_blend_color = nv30_set_blend_color; + nv30->pipe.set_stencil_ref = nv30_set_stencil_ref; nv30->pipe.set_clip_state = nv30_set_clip_state; nv30->pipe.set_constant_buffer = nv30_set_constant_buffer; nv30->pipe.set_framebuffer_state = nv30_set_framebuffer_state; diff --git a/src/gallium/drivers/nv30/nv30_state_emit.c b/src/gallium/drivers/nv30/nv30_state_emit.c index d9650f63eb..deefe7fd8d 100644 --- a/src/gallium/drivers/nv30/nv30_state_emit.c +++ b/src/gallium/drivers/nv30/nv30_state_emit.c @@ -12,6 +12,7 @@ static struct nv30_state_entry *render_states[] = { &nv30_state_blend, &nv30_state_blend_colour, &nv30_state_zsa, + &nv30_state_sr, &nv30_state_viewport, &nv30_state_vbo, NULL diff --git a/src/gallium/drivers/nv30/nv30_state_zsa.c b/src/gallium/drivers/nv30/nv30_state_zsa.c index 0940b7269b..88cd74f180 100644 --- a/src/gallium/drivers/nv30/nv30_state_zsa.c +++ b/src/gallium/drivers/nv30/nv30_state_zsa.c @@ -15,3 +15,27 @@ struct nv30_state_entry nv30_state_zsa = { .hw = NV30_STATE_ZSA } }; + +static boolean +nv30_state_sr_validate(struct nv30_context *nv30) +{ + struct nouveau_stateobj *so = so_new(2, 2, 0); + struct pipe_stencil_ref *sr = &nv30->stencil_ref; + + so_method(so, nv30->screen->rankine, NV34TCL_STENCIL_FRONT_FUNC_REF, 1); + so_data (so, sr->ref_value[0]); + so_method(so, nv30->screen->rankine, NV34TCL_STENCIL_BACK_FUNC_REF, 1); + so_data (so, sr->ref_value[1]); + + so_ref(so, &nv30->state.hw[NV30_STATE_SR]); + so_ref(NULL, &so); + return TRUE; +} + +struct nv30_state_entry nv30_state_sr = { + .validate = nv30_state_sr_validate, + .dirty = { + .pipe = NV30_NEW_SR, + .hw = NV30_STATE_SR + } +}; diff --git a/src/gallium/drivers/nv30/nv30_vbo.c b/src/gallium/drivers/nv30/nv30_vbo.c index a83ddf1154..e48823a913 100644 --- a/src/gallium/drivers/nv30/nv30_vbo.c +++ b/src/gallium/drivers/nv30/nv30_vbo.c @@ -1,6 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_inlines.h" +#include "util/u_format.h" #include "nv30_context.h" #include "nv30_state.h" @@ -34,7 +35,7 @@ nv30_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *fmt = NV34TCL_VTXFMT_TYPE_USHORT; break; default: - NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); + NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe)); return 1; } @@ -60,7 +61,7 @@ nv30_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *ncomp = 4; break; default: - NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); + NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe)); return 1; } @@ -185,7 +186,7 @@ nv30_draw_arrays(struct pipe_context *pipe, nv30_state_emit(nv30); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256, mode, start, count, &restart); if (!vc) { FIRE_RING(chan); @@ -239,7 +240,7 @@ nv30_draw_elements_u08(struct nv30_context *nv30, void *ib, nv30_state_emit(nv30); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2, mode, start, count, &restart); if (vc == 0) { FIRE_RING(chan); @@ -290,7 +291,7 @@ nv30_draw_elements_u16(struct nv30_context *nv30, void *ib, nv30_state_emit(nv30); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2, mode, start, count, &restart); if (vc == 0) { FIRE_RING(chan); @@ -341,7 +342,7 @@ nv30_draw_elements_u32(struct nv30_context *nv30, void *ib, nv30_state_emit(nv30); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1, mode, start, count, &restart); if (vc == 0) { FIRE_RING(chan); @@ -417,7 +418,7 @@ nv30_draw_elements_vbo(struct pipe_context *pipe, nv30_state_emit(nv30); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256, mode, start, count, &restart); if (!vc) { FIRE_RING(chan); diff --git a/src/gallium/drivers/nv40/nv40_context.h b/src/gallium/drivers/nv40/nv40_context.h index 958a48f2a4..4861924dac 100644 --- a/src/gallium/drivers/nv40/nv40_context.h +++ b/src/gallium/drivers/nv40/nv40_context.h @@ -61,7 +61,8 @@ enum nv40_state_index { NV40_STATE_VTXBUF = 31, NV40_STATE_VTXFMT = 32, NV40_STATE_VTXATTR = 33, - NV40_STATE_MAX = 34 + NV40_STATE_SR = 34, + NV40_STATE_MAX = 35 }; #include "nv40_screen.h" @@ -79,6 +80,7 @@ enum nv40_state_index { #define NV40_NEW_FRAGPROG (1 << 10) #define NV40_NEW_ARRAYS (1 << 11) #define NV40_NEW_UCP (1 << 12) +#define NV40_NEW_SR (1 << 13) struct nv40_rasterizer_state { struct pipe_rasterizer_state pipe; @@ -144,6 +146,7 @@ struct nv40_context { struct nv40_zsa_state *zsa; struct nv40_blend_state *blend; struct pipe_blend_color blend_colour; + struct pipe_stencil_ref stencil_ref; struct pipe_viewport_state viewport; struct pipe_framebuffer_state framebuffer; struct pipe_buffer *idxbuf; @@ -215,6 +218,7 @@ extern struct nv40_state_entry nv40_state_framebuffer; extern struct nv40_state_entry nv40_state_fragtex; extern struct nv40_state_entry nv40_state_vbo; extern struct nv40_state_entry nv40_state_vtxfmt; +extern struct nv40_state_entry nv40_state_sr; /* nv40_vbo.c */ extern void nv40_draw_arrays(struct pipe_context *, unsigned mode, diff --git a/src/gallium/drivers/nv40/nv40_draw.c b/src/gallium/drivers/nv40/nv40_draw.c index 60ab49fad1..48bd84d16c 100644 --- a/src/gallium/drivers/nv40/nv40_draw.c +++ b/src/gallium/drivers/nv40/nv40_draw.c @@ -88,12 +88,11 @@ nv40_render_prim(struct draw_stage *stage, struct prim_header *prim, struct nv40_screen *screen = nv40->screen; struct nouveau_channel *chan = screen->base.channel; - struct nouveau_pushbuf *pb = chan->pushbuf; struct nouveau_grobj *curie = screen->curie; unsigned i; /* Ensure there's room for 4xfloat32 + potentially 3 begin/end */ - if (pb->remaining < ((count * 20) + 6)) { + if (AVAIL_RING(chan) < ((count * 20) + 6)) { if (rs->prim != NV40TCL_BEGIN_END_STOP) { NOUVEAU_ERR("AIII, missed flush\n"); assert(0); @@ -121,7 +120,7 @@ nv40_render_prim(struct draw_stage *stage, struct prim_header *prim, /* If it's likely we'll need to empty the push buffer soon, finish * off the primitive now. */ - if (pb->remaining < ((count * 20) + 6)) { + if (AVAIL_RING(chan) < ((count * 20) + 6)) { BEGIN_RING(chan, curie, NV40TCL_BEGIN_END, 1); OUT_RING (chan, NV40TCL_BEGIN_END_STOP); rs->prim = NV40TCL_BEGIN_END_STOP; diff --git a/src/gallium/drivers/nv40/nv40_fragtex.c b/src/gallium/drivers/nv40/nv40_fragtex.c index aad9198210..7a28d577b1 100644 --- a/src/gallium/drivers/nv40/nv40_fragtex.c +++ b/src/gallium/drivers/nv40/nv40_fragtex.c @@ -1,3 +1,5 @@ +#include "util/u_format.h" + #include "nv40_context.h" #define _(m,tf,ts0x,ts0y,ts0z,ts0w,ts1x,ts1y,ts1z,ts1w,sx,sy,sz,sw) \ @@ -53,7 +55,7 @@ nv40_fragtex_format(uint pipe_format) tf++; } - NOUVEAU_ERR("unknown texture format %s\n", pf_name(pipe_format)); + NOUVEAU_ERR("unknown texture format %s\n", util_format_name(pipe_format)); return NULL; } diff --git a/src/gallium/drivers/nv40/nv40_screen.c b/src/gallium/drivers/nv40/nv40_screen.c index 001147e752..edee4b9a3a 100644 --- a/src/gallium/drivers/nv40/nv40_screen.c +++ b/src/gallium/drivers/nv40/nv40_screen.c @@ -62,6 +62,8 @@ nv40_screen_get_param(struct pipe_screen *pscreen, int param) case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER: return 0; + case PIPE_CAP_MAX_COMBINED_SAMPLERS: + return 16; default: NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param); return 0; diff --git a/src/gallium/drivers/nv40/nv40_state.c b/src/gallium/drivers/nv40/nv40_state.c index 51b40e51e4..4f28675e64 100644 --- a/src/gallium/drivers/nv40/nv40_state.c +++ b/src/gallium/drivers/nv40/nv40_state.c @@ -132,26 +132,26 @@ nv40_sampler_state_create(struct pipe_context *pipe, (wrap_mode(cso->wrap_r) << NV40TCL_TEX_WRAP_R_SHIFT)); ps->en = 0; - if (cso->max_anisotropy >= 2.0) { + if (cso->max_anisotropy >= 2) { /* no idea, binary driver sets it, works without it.. meh.. */ ps->wrap |= (1 << 5); - if (cso->max_anisotropy >= 16.0) { + if (cso->max_anisotropy >= 16) { ps->en |= NV40TCL_TEX_ENABLE_ANISO_16X; } else - if (cso->max_anisotropy >= 12.0) { + if (cso->max_anisotropy >= 12) { ps->en |= NV40TCL_TEX_ENABLE_ANISO_12X; } else - if (cso->max_anisotropy >= 10.0) { + if (cso->max_anisotropy >= 10) { ps->en |= NV40TCL_TEX_ENABLE_ANISO_10X; } else - if (cso->max_anisotropy >= 8.0) { + if (cso->max_anisotropy >= 8) { ps->en |= NV40TCL_TEX_ENABLE_ANISO_8X; } else - if (cso->max_anisotropy >= 6.0) { + if (cso->max_anisotropy >= 6) { ps->en |= NV40TCL_TEX_ENABLE_ANISO_6X; } else - if (cso->max_anisotropy >= 4.0) { + if (cso->max_anisotropy >= 4) { ps->en |= NV40TCL_TEX_ENABLE_ANISO_4X; } else { ps->en |= NV40TCL_TEX_ENABLE_ANISO_2X; @@ -310,7 +310,7 @@ nv40_rasterizer_state_create(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct nv40_rasterizer_state *rsso = CALLOC(1, sizeof(*rsso)); - struct nouveau_stateobj *so = so_new(8, 18, 0); + struct nouveau_stateobj *so = so_new(9, 19, 0); struct nouveau_grobj *curie = nv40->screen->curie; /*XXX: ignored: @@ -445,7 +445,7 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, { struct nv40_context *nv40 = nv40_context(pipe); struct nv40_zsa_state *zsaso = CALLOC(1, sizeof(*zsaso)); - struct nouveau_stateobj *so = so_new(4, 21, 0); + struct nouveau_stateobj *so = so_new(6, 20, 0); struct nouveau_grobj *curie = nv40->screen->curie; so_method(so, curie, NV40TCL_DEPTH_FUNC, 3); @@ -459,11 +459,11 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, float_to_ubyte(cso->alpha.ref_value)); if (cso->stencil[0].enabled) { - so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, curie, NV40TCL_STENCIL_FRONT_ENABLE, 3); so_data (so, cso->stencil[0].enabled ? 1 : 0); so_data (so, cso->stencil[0].writemask); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); - so_data (so, cso->stencil[0].ref_value); + so_method(so, curie, NV40TCL_STENCIL_FRONT_FUNC_MASK, 4); so_data (so, cso->stencil[0].valuemask); so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); @@ -474,11 +474,11 @@ nv40_depth_stencil_alpha_state_create(struct pipe_context *pipe, } if (cso->stencil[1].enabled) { - so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 8); + so_method(so, curie, NV40TCL_STENCIL_BACK_ENABLE, 3); so_data (so, cso->stencil[1].enabled ? 1 : 0); so_data (so, cso->stencil[1].writemask); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); - so_data (so, cso->stencil[1].ref_value); + so_method(so, curie, NV40TCL_STENCIL_BACK_FUNC_MASK, 4); so_data (so, cso->stencil[1].valuemask); so_data (so, nvgl_stencil_op(cso->stencil[1].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); @@ -592,6 +592,16 @@ nv40_set_blend_color(struct pipe_context *pipe, nv40->dirty |= NV40_NEW_BCOL; } + static void +nv40_set_stencil_ref(struct pipe_context *pipe, + const struct pipe_stencil_ref *sr) +{ + struct nv40_context *nv40 = nv40_context(pipe); + + nv40->stencil_ref = *sr; + nv40->dirty |= NV40_NEW_SR; +} + static void nv40_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) @@ -719,6 +729,7 @@ nv40_init_state_functions(struct nv40_context *nv40) nv40->pipe.delete_fs_state = nv40_fp_state_delete; nv40->pipe.set_blend_color = nv40_set_blend_color; + nv40->pipe.set_stencil_ref = nv40_set_stencil_ref; nv40->pipe.set_clip_state = nv40_set_clip_state; nv40->pipe.set_constant_buffer = nv40_set_constant_buffer; nv40->pipe.set_framebuffer_state = nv40_set_framebuffer_state; diff --git a/src/gallium/drivers/nv40/nv40_state_emit.c b/src/gallium/drivers/nv40/nv40_state_emit.c index 1c4007a129..8990f303ce 100644 --- a/src/gallium/drivers/nv40/nv40_state_emit.c +++ b/src/gallium/drivers/nv40/nv40_state_emit.c @@ -13,6 +13,7 @@ static struct nv40_state_entry *render_states[] = { &nv40_state_blend, &nv40_state_blend_colour, &nv40_state_zsa, + &nv40_state_sr, &nv40_state_viewport, &nv40_state_vbo, NULL @@ -29,6 +30,7 @@ static struct nv40_state_entry *swtnl_states[] = { &nv40_state_blend, &nv40_state_blend_colour, &nv40_state_zsa, + &nv40_state_sr, &nv40_state_viewport, &nv40_state_vtxfmt, NULL diff --git a/src/gallium/drivers/nv40/nv40_state_zsa.c b/src/gallium/drivers/nv40/nv40_state_zsa.c index fb760677c8..9cbe7da6db 100644 --- a/src/gallium/drivers/nv40/nv40_state_zsa.c +++ b/src/gallium/drivers/nv40/nv40_state_zsa.c @@ -15,3 +15,27 @@ struct nv40_state_entry nv40_state_zsa = { .hw = NV40_STATE_ZSA } }; + +static boolean +nv40_state_sr_validate(struct nv40_context *nv40) +{ + struct nouveau_stateobj *so = so_new(2, 2, 0); + struct pipe_stencil_ref *sr = &nv40->stencil_ref; + + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_FRONT_FUNC_REF, 1); + so_data (so, sr->ref_value[0]); + so_method(so, nv40->screen->curie, NV40TCL_STENCIL_BACK_FUNC_REF, 1); + so_data (so, sr->ref_value[1]); + + so_ref(so, &nv40->state.hw[NV40_STATE_SR]); + so_ref(NULL, &so); + return TRUE; +} + +struct nv40_state_entry nv40_state_sr = { + .validate = nv40_state_sr_validate, + .dirty = { + .pipe = NV40_NEW_SR, + .hw = NV40_STATE_SR + } +}; diff --git a/src/gallium/drivers/nv40/nv40_vbo.c b/src/gallium/drivers/nv40/nv40_vbo.c index 1e14edc56a..7812460d2e 100644 --- a/src/gallium/drivers/nv40/nv40_vbo.c +++ b/src/gallium/drivers/nv40/nv40_vbo.c @@ -1,6 +1,7 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_inlines.h" +#include "util/u_format.h" #include "nv40_context.h" #include "nv40_state.h" @@ -34,7 +35,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *fmt = NV40TCL_VTXFMT_TYPE_USHORT; break; default: - NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); + NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe)); return 1; } @@ -60,7 +61,7 @@ nv40_vbo_format_to_hw(enum pipe_format pipe, unsigned *fmt, unsigned *ncomp) *ncomp = 4; break; default: - NOUVEAU_ERR("Unknown format %s\n", pf_name(pipe)); + NOUVEAU_ERR("Unknown format %s\n", util_format_name(pipe)); return 1; } @@ -186,7 +187,7 @@ nv40_draw_arrays(struct pipe_context *pipe, nv40_state_emit(nv40); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256, mode, start, count, &restart); if (!vc) { FIRE_RING(chan); @@ -240,7 +241,7 @@ nv40_draw_elements_u08(struct nv40_context *nv40, void *ib, nv40_state_emit(nv40); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2, mode, start, count, &restart); if (vc == 0) { FIRE_RING(chan); @@ -291,7 +292,7 @@ nv40_draw_elements_u16(struct nv40_context *nv40, void *ib, nv40_state_emit(nv40); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 2, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 2, mode, start, count, &restart); if (vc == 0) { FIRE_RING(chan); @@ -342,7 +343,7 @@ nv40_draw_elements_u32(struct nv40_context *nv40, void *ib, nv40_state_emit(nv40); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 5, 1, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 5, 1, mode, start, count, &restart); if (vc == 0) { FIRE_RING(chan); @@ -418,7 +419,7 @@ nv40_draw_elements_vbo(struct pipe_context *pipe, nv40_state_emit(nv40); - vc = nouveau_vbuf_split(chan->pushbuf->remaining, 6, 256, + vc = nouveau_vbuf_split(AVAIL_RING(chan), 6, 256, mode, start, count, &restart); if (!vc) { FIRE_RING(chan); diff --git a/src/gallium/drivers/nv50/nv50_context.h b/src/gallium/drivers/nv50/nv50_context.h index 14cef4c0bf..b4de3e2ba5 100644 --- a/src/gallium/drivers/nv50/nv50_context.h +++ b/src/gallium/drivers/nv50/nv50_context.h @@ -50,6 +50,7 @@ #define NV50_NEW_ARRAYS (1 << 14) #define NV50_NEW_SAMPLER (1 << 15) #define NV50_NEW_TEXTURE (1 << 16) +#define NV50_NEW_STENCIL_REF (1 << 17) struct nv50_blend_stateobj { struct pipe_blend_state pipe; @@ -120,6 +121,7 @@ struct nv50_state { struct nouveau_stateobj *blend; struct nouveau_stateobj *blend_colour; struct nouveau_stateobj *zsa; + struct nouveau_stateobj *stencil_ref; struct nouveau_stateobj *rast; struct nouveau_stateobj *stipple; struct nouveau_stateobj *scissor; @@ -155,6 +157,7 @@ struct nv50_context { struct nv50_zsa_stateobj *zsa; struct nv50_rasterizer_stateobj *rasterizer; struct pipe_blend_color blend_colour; + struct pipe_stencil_ref stencil_ref; struct pipe_poly_stipple stipple; struct pipe_scissor_state scissor; struct pipe_viewport_state viewport; diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c index 8c4478e483..2232461b9b 100644 --- a/src/gallium/drivers/nv50/nv50_screen.c +++ b/src/gallium/drivers/nv50/nv50_screen.c @@ -134,7 +134,7 @@ nv50_screen_get_param(struct pipe_screen *pscreen, int param) case NOUVEAU_CAP_HW_VTXBUF: return 1; case NOUVEAU_CAP_HW_IDXBUF: - return 0; + return 1; case PIPE_CAP_INDEP_BLEND_ENABLE: return 1; case PIPE_CAP_INDEP_BLEND_FUNC: diff --git a/src/gallium/drivers/nv50/nv50_state.c b/src/gallium/drivers/nv50/nv50_state.c index 7c531b50a5..7d304907b6 100644 --- a/src/gallium/drivers/nv50/nv50_state.c +++ b/src/gallium/drivers/nv50/nv50_state.c @@ -202,18 +202,18 @@ nv50_sampler_state_create(struct pipe_context *pipe, break; } - if (cso->max_anisotropy >= 16.0) + if (cso->max_anisotropy >= 16) tsc[0] |= (7 << 20); else - if (cso->max_anisotropy >= 12.0) + if (cso->max_anisotropy >= 12) tsc[0] |= (6 << 20); else { - tsc[0] |= (int)(cso->max_anisotropy * 0.5f) << 20; + tsc[0] |= (cso->max_anisotropy >> 1) << 20; - if (cso->max_anisotropy >= 4.0) + if (cso->max_anisotropy >= 4) tsc[1] |= NV50TSC_1_1_UNKN_ANISO_35; else - if (cso->max_anisotropy >= 2.0) + if (cso->max_anisotropy >= 2) tsc[1] |= NV50TSC_1_1_UNKN_ANISO_15; } @@ -447,7 +447,7 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, { struct nouveau_grobj *tesla = nv50_context(pipe)->screen->tesla; struct nv50_zsa_stateobj *zsa = CALLOC_STRUCT(nv50_zsa_stateobj); - struct nouveau_stateobj *so = so_new(8, 22, 0); + struct nouveau_stateobj *so = so_new(9, 21, 0); so_method(so, tesla, NV50TCL_DEPTH_WRITE_ENABLE, 1); so_data (so, cso->depth.writemask ? 1 : 0); @@ -462,13 +462,13 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, } if (cso->stencil[0].enabled) { - so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 8); + so_method(so, tesla, NV50TCL_STENCIL_FRONT_ENABLE, 5); so_data (so, 1); so_data (so, nvgl_stencil_op(cso->stencil[0].fail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[0].zpass_op)); so_data (so, nvgl_comparison_op(cso->stencil[0].func)); - so_data (so, cso->stencil[0].ref_value); + so_method(so, tesla, NV50TCL_STENCIL_FRONT_MASK, 2); so_data (so, cso->stencil[0].writemask); so_data (so, cso->stencil[0].valuemask); } else { @@ -483,8 +483,7 @@ nv50_depth_stencil_alpha_state_create(struct pipe_context *pipe, so_data (so, nvgl_stencil_op(cso->stencil[1].zfail_op)); so_data (so, nvgl_stencil_op(cso->stencil[1].zpass_op)); so_data (so, nvgl_comparison_op(cso->stencil[1].func)); - so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 3); - so_data (so, cso->stencil[1].ref_value); + so_method(so, tesla, NV50TCL_STENCIL_BACK_MASK, 2); so_data (so, cso->stencil[1].writemask); so_data (so, cso->stencil[1].valuemask); } else { @@ -633,6 +632,16 @@ nv50_set_blend_color(struct pipe_context *pipe, nv50->dirty |= NV50_NEW_BLEND_COLOUR; } + static void +nv50_set_stencil_ref(struct pipe_context *pipe, + const struct pipe_stencil_ref *sr) +{ + struct nv50_context *nv50 = nv50_context(pipe); + + nv50->stencil_ref = *sr; + nv50->dirty |= NV50_NEW_STENCIL_REF; +} + static void nv50_set_clip_state(struct pipe_context *pipe, const struct pipe_clip_state *clip) @@ -761,6 +770,7 @@ nv50_init_state_functions(struct nv50_context *nv50) nv50->pipe.delete_gs_state = nv50_gp_state_delete; nv50->pipe.set_blend_color = nv50_set_blend_color; + nv50->pipe.set_stencil_ref = nv50_set_stencil_ref; nv50->pipe.set_clip_state = nv50_set_clip_state; nv50->pipe.set_constant_buffer = nv50_set_constant_buffer; nv50->pipe.set_framebuffer_state = nv50_set_framebuffer_state; diff --git a/src/gallium/drivers/nv50/nv50_state_validate.c b/src/gallium/drivers/nv50/nv50_state_validate.c index ee28fa63c1..efab94cab7 100644 --- a/src/gallium/drivers/nv50/nv50_state_validate.c +++ b/src/gallium/drivers/nv50/nv50_state_validate.c @@ -20,6 +20,8 @@ * SOFTWARE. */ +#include "util/u_format.h" + #include "nv50_context.h" #include "nouveau/nouveau_stateobj.h" @@ -79,7 +81,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) NV50_CBUF_FORMAT_CASE(R16G16_UNORM); default: NOUVEAU_ERR("AIIII unknown format %s\n", - pf_name(fb->cbufs[i]->format)); + util_format_name(fb->cbufs[i]->format)); so_data(so, NV50TCL_RT_FORMAT_X8R8G8B8_UNORM); break; } @@ -116,7 +118,7 @@ nv50_state_validate_fb(struct nv50_context *nv50) NV50_ZETA_FORMAT_CASE(Z32_FLOAT); default: NOUVEAU_ERR("AIIII unknown format %s\n", - pf_name(fb->zsbuf->format)); + util_format_name(fb->zsbuf->format)); so_data(so, NV50TCL_ZETA_FORMAT_S8Z24_UNORM); break; } @@ -205,6 +207,8 @@ nv50_state_emit(struct nv50_context *nv50) nv50->state.dirty |= NV50_NEW_RASTERIZER; if (nv50->state.blend_colour) nv50->state.dirty |= NV50_NEW_BLEND_COLOUR; + if (nv50->state.stencil_ref) + nv50->state.dirty |= NV50_NEW_STENCIL_REF; if (nv50->state.stipple) nv50->state.dirty |= NV50_NEW_STIPPLE; if (nv50->state.scissor) @@ -242,6 +246,8 @@ nv50_state_emit(struct nv50_context *nv50) so_emit(chan, nv50->state.rast); if (nv50->state.dirty & NV50_NEW_BLEND_COLOUR) so_emit(chan, nv50->state.blend_colour); + if (nv50->state.dirty & NV50_NEW_STENCIL_REF) + so_emit(chan, nv50->state.stencil_ref); if (nv50->state.dirty & NV50_NEW_STIPPLE) so_emit(chan, nv50->state.stipple); if (nv50->state.dirty & NV50_NEW_SCISSOR) @@ -325,6 +331,16 @@ nv50_state_validate(struct nv50_context *nv50) so_ref(NULL, &so); } + if (nv50->dirty & NV50_NEW_STENCIL_REF) { + so = so_new(2, 2, 0); + so_method(so, tesla, NV50TCL_STENCIL_FRONT_FUNC_REF, 1); + so_data (so, nv50->stencil_ref.ref_value[0]); + so_method(so, tesla, NV50TCL_STENCIL_BACK_FUNC_REF, 1); + so_data (so, nv50->stencil_ref.ref_value[1]); + so_ref(so, &nv50->state.stencil_ref); + so_ref(NULL, &so); + } + if (nv50->dirty & NV50_NEW_STIPPLE) { so = so_new(1, 32, 0); so_method(so, tesla, NV50TCL_POLYGON_STIPPLE_PATTERN(0), 32); diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c index d08b4d7354..7c360e9e73 100644 --- a/src/gallium/drivers/nv50/nv50_transfer.c +++ b/src/gallium/drivers/nv50/nv50_transfer.c @@ -313,7 +313,7 @@ nv50_upload_sifc(struct nv50_context *nv50, while (count) { unsigned nr = MIN2(count, 1792); - if (chan->pushbuf->remaining <= nr) { + if (AVAIL_RING(chan) <= nr) { FIRE_RING (chan); BEGIN_RING(chan, eng2d, @@ -321,7 +321,7 @@ nv50_upload_sifc(struct nv50_context *nv50, OUT_RELOCh(chan, bo, dst_offset, reloc); OUT_RELOCl(chan, bo, dst_offset, reloc); } - assert(chan->pushbuf->remaining > nr); + assert(AVAIL_RING(chan) > nr); BEGIN_RING(chan, eng2d, NV50_2D_SIFC_DATA | (2 << 29), nr); diff --git a/src/gallium/drivers/nv50/nv50_vbo.c b/src/gallium/drivers/nv50/nv50_vbo.c index ca2f8061f3..1c8ee0b9ad 100644 --- a/src/gallium/drivers/nv50/nv50_vbo.c +++ b/src/gallium/drivers/nv50/nv50_vbo.c @@ -23,7 +23,6 @@ #include "pipe/p_context.h" #include "pipe/p_state.h" #include "util/u_inlines.h" - #include "util/u_format.h" #include "nv50_context.h" @@ -151,7 +150,7 @@ nv50_vbo_vtxelt_to_hw(struct pipe_vertex_element *ve) hw_size = nv50_vbo_size_to_hw(size, ve->nr_components); if (!hw_type || !hw_size) { - NOUVEAU_ERR("unsupported vbo format: %s\n", pf_name(pf)); + NOUVEAU_ERR("unsupported vbo format: %s\n", util_format_name(pf)); abort(); return 0x24e80000; } @@ -674,8 +673,6 @@ nv50_draw_elements(struct pipe_context *pipe, struct pipe_screen *pscreen = pipe->screen; void *map; - map = pipe_buffer_map(pscreen, indexBuffer, PIPE_BUFFER_USAGE_CPU_READ); - nv50_state_validate(nv50); BEGIN_RING(chan, tesla, 0x142c, 1); @@ -686,14 +683,35 @@ nv50_draw_elements(struct pipe_context *pipe, BEGIN_RING(chan, tesla, NV50TCL_VERTEX_BEGIN, 1); OUT_RING (chan, nv50_prim(mode)); - nv50_draw_elements_inline(nv50, map, indexSize, start, count); + if (!nv50->vbo_fifo && indexSize == 4) { + BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U32 | 0x30000, 0); + OUT_RING (chan, count); + nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer), + start << 2, count << 2); + } else + if (!nv50->vbo_fifo && indexSize == 2) { + unsigned vb_start = (start & ~1); + unsigned vb_end = (start + count + 1) & ~1; + unsigned dwords = (vb_end - vb_start) >> 1; + + BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1); + OUT_RING (chan, ((start & 1) << 31) | count); + BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16 | 0x30000, 0); + OUT_RING (chan, dwords); + nouveau_pushbuf_submit(chan, nouveau_bo(indexBuffer), + vb_start << 1, dwords << 2); + BEGIN_RING(chan, tesla, NV50TCL_VB_ELEMENT_U16_SETUP, 1); + OUT_RING (chan, 0); + } else { + map = pipe_buffer_map(pscreen, indexBuffer, + PIPE_BUFFER_USAGE_CPU_READ); + nv50_draw_elements_inline(nv50, map, indexSize, start, count); + nv50_unmap_vbufs(nv50); + pipe_buffer_unmap(pscreen, indexBuffer); + } BEGIN_RING(chan, tesla, NV50TCL_VERTEX_END, 1); OUT_RING (chan, 0); - - nv50_unmap_vbufs(nv50); - - pipe_buffer_unmap(pscreen, indexBuffer); } static INLINE boolean diff --git a/src/gallium/drivers/r300/r300_blit.c b/src/gallium/drivers/r300/r300_blit.c index cdedb30220..eb9b0beeb5 100644 --- a/src/gallium/drivers/r300/r300_blit.c +++ b/src/gallium/drivers/r300/r300_blit.c @@ -22,11 +22,15 @@ #include "r300_blit.h" #include "r300_context.h" +#include "r300_texture.h" + +#include "util/u_format.h" static void r300_blitter_save_states(struct r300_context* r300) { util_blitter_save_blend(r300->blitter, r300->blend_state.state); util_blitter_save_depth_stencil_alpha(r300->blitter, r300->dsa_state.state); + util_blitter_save_stencil_ref(r300->blitter, &(r300->stencil_ref)); util_blitter_save_rasterizer(r300->blitter, r300->rs_state.state); util_blitter_save_fragment_shader(r300->blitter, r300->fs); util_blitter_save_vertex_shader(r300->blitter, r300->vs); @@ -85,13 +89,13 @@ void r300_clear(struct pipe_context* pipe, buffers, rgba, depth, stencil); } -/* Copy a block of pixels from one surface to another. */ -void r300_surface_copy(struct pipe_context* pipe, - struct pipe_surface* dst, - unsigned dstx, unsigned dsty, - struct pipe_surface* src, - unsigned srcx, unsigned srcy, - unsigned width, unsigned height) +/* Copy a block of pixels from one surface to another using HW. */ +static void r300_hw_copy(struct pipe_context* pipe, + struct pipe_surface* dst, + unsigned dstx, unsigned dsty, + struct pipe_surface* src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) { struct r300_context* r300 = r300_context(pipe); @@ -113,6 +117,63 @@ void r300_surface_copy(struct pipe_context* pipe, dst, dstx, dsty, src, srcx, srcy, width, height, TRUE); } +/* Copy a block of pixels from one surface to another. */ +void r300_surface_copy(struct pipe_context* pipe, + struct pipe_surface* dst, + unsigned dstx, unsigned dsty, + struct pipe_surface* src, + unsigned srcx, unsigned srcy, + unsigned width, unsigned height) +{ + enum pipe_format old_format = dst->texture->format; + enum pipe_format new_format = old_format; + + assert(dst->texture->format == src->texture->format); + + if (!pipe->screen->is_format_supported(pipe->screen, + old_format, src->texture->target, + PIPE_TEXTURE_USAGE_RENDER_TARGET | + PIPE_TEXTURE_USAGE_SAMPLER, 0)) { + switch (util_format_get_blocksize(old_format)) { + case 1: + new_format = PIPE_FORMAT_I8_UNORM; + break; + case 2: + new_format = PIPE_FORMAT_A4R4G4B4_UNORM; + break; + case 4: + new_format = PIPE_FORMAT_A8R8G8B8_UNORM; + break; + default: + debug_printf("r300: surface_copy: Unhandled format: %s. Falling back to software.\n" + "r300: surface_copy: Software fallback doesn't work for tiled textures.\n", + util_format_name(old_format)); + } + } + + if (old_format != new_format) { + dst->format = new_format; + src->format = new_format; + + r300_texture_reinterpret_format(pipe->screen, + dst->texture, new_format); + r300_texture_reinterpret_format(pipe->screen, + src->texture, new_format); + } + + r300_hw_copy(pipe, dst, dstx, dsty, src, srcx, srcy, width, height); + + if (old_format != new_format) { + dst->format = old_format; + src->format = old_format; + + r300_texture_reinterpret_format(pipe->screen, + dst->texture, old_format); + r300_texture_reinterpret_format(pipe->screen, + src->texture, old_format); + } +} + /* Fill a region of a surface with a constant value. */ void r300_surface_fill(struct pipe_context* pipe, struct pipe_surface* dst, diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c index 14820ca854..f631b4ed27 100644 --- a/src/gallium/drivers/r300/r300_context.c +++ b/src/gallium/drivers/r300/r300_context.c @@ -34,7 +34,8 @@ #include "r300_screen.h" #include "r300_state_invariant.h" #include "r300_texture.h" -#include "r300_winsys.h" + +#include "radeon_winsys.h" static void r300_destroy_context(struct pipe_context* context) { diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h index 8461757812..1eba8a8ed1 100644 --- a/src/gallium/drivers/r300/r300_context.h +++ b/src/gallium/drivers/r300/r300_context.h @@ -155,8 +155,7 @@ struct r300_ztop_state { struct r300_constant_buffer { /* Buffer of constants */ - /* XXX first number should be raised */ - float constants[32][4]; + float constants[256][4]; /* Total number of constants */ unsigned count; }; @@ -207,6 +206,9 @@ struct r300_texture { /* Size of one zslice or face based on the texture target */ unsigned layer_size[PIPE_MAX_TEXTURE_LEVELS]; + /* Whether the mipmap level is macrotiled. */ + enum r300_buffer_tiling mip_macrotile[PIPE_MAX_TEXTURE_LEVELS]; + /** * If non-zero, override the natural texture layout with * a custom stride (in bytes). @@ -318,6 +320,8 @@ struct r300_context { struct pipe_vertex_element vertex_element[PIPE_MAX_ATTRIBS]; int vertex_element_count; + struct pipe_stencil_ref stencil_ref; + /* Bitmask of dirty state objects. */ uint32_t dirty_state; /* Flag indicating whether or not the HW is dirty. */ diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c index de6ba651d1..88fe166359 100644 --- a/src/gallium/drivers/r300/r300_emit.c +++ b/src/gallium/drivers/r300/r300_emit.c @@ -114,6 +114,7 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state) struct r300_screen* r300screen = r300_screen(r300->context.screen); struct pipe_framebuffer_state* fb = (struct pipe_framebuffer_state*)r300->fb_state.state; + struct pipe_stencil_ref stencil_ref = r300->stencil_ref; CS_LOCALS(r300); BEGIN_CS(r300screen->caps->is_r500 ? 8 : 6); @@ -128,10 +129,10 @@ void r300_emit_dsa_state(struct r300_context* r300, void* state) OUT_CS(0); } - OUT_CS(dsa->stencil_ref_mask); + OUT_CS(dsa->stencil_ref_mask | stencil_ref.ref_value[0]); if (r300screen->caps->is_r500) { - OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf); + OUT_CS_REG(R500_ZB_STENCILREFMASK_BF, dsa->stencil_ref_bf | stencil_ref.ref_value[1]); } END_CS; } @@ -387,8 +388,7 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) int i; CS_LOCALS(r300); - BEGIN_CS((10 * fb->nr_cbufs) + (2 * (4 - fb->nr_cbufs)) + - (fb->zsbuf ? 10 : 0) + 6); + BEGIN_CS((10 * fb->nr_cbufs) + (fb->zsbuf ? 10 : 0) + 6); /* Flush and free renderbuffer caches. */ OUT_CS_REG(R300_RB3D_DSTCACHE_CTLSTAT, @@ -403,12 +403,10 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) if (r300screen->caps->is_r500) { OUT_CS_REG(R300_RB3D_CCTL, R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) | - R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE | - R300_RB3D_CCTL_INDEPENDENT_COLOR_CHANNEL_MASK_ENABLE); + R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE); } else { OUT_CS_REG(R300_RB3D_CCTL, - R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs) | - R300_RB3D_CCTL_INDEPENDENT_COLORFORMAT_ENABLE_ENABLE); + R300_RB3D_CCTL_NUM_MULTIWRITES(fb->nr_cbufs)); } } else { OUT_CS_REG(R300_RB3D_CCTL, 0x0); @@ -426,7 +424,7 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) OUT_CS_REG_SEQ(R300_RB3D_COLORPITCH0 + (4 * i), 1); OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] | r300_translate_colorformat(tex->tex.format) | - R300_COLOR_TILE(tex->macrotile) | + R300_COLOR_TILE(tex->mip_macrotile[surf->level]) | R300_COLOR_MICROTILE(tex->microtile), 0, RADEON_GEM_DOMAIN_VRAM, 0); @@ -434,11 +432,6 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) r300_translate_out_fmt(surf->format)); } - /* Disable unused colorbuffers. */ - for (; i < 4; i++) { - OUT_CS_REG(R300_US_OUT_FMT_0 + (4 * i), R300_US_OUT_FMT_UNUSED); - } - /* Set up a zbuffer. */ if (fb->zsbuf) { surf = fb->zsbuf; @@ -452,7 +445,7 @@ void r300_emit_fb_state(struct r300_context* r300, void* state) OUT_CS_REG_SEQ(R300_ZB_DEPTHPITCH, 1); OUT_CS_RELOC(tex->buffer, tex->pitch[surf->level] | - R300_DEPTHMACROTILE(tex->macrotile) | + R300_DEPTHMACROTILE(tex->mip_macrotile[surf->level]) | R300_DEPTHMICROTILE(tex->microtile), 0, RADEON_GEM_DOMAIN_VRAM, 0); } @@ -636,17 +629,19 @@ void r300_emit_rs_block_state(struct r300_context* r300, void* state) struct r300_rs_block* rs = (struct r300_rs_block*)state; unsigned i; struct r300_screen* r300screen = r300_screen(r300->context.screen); + /* It's the same for both INST and IP tables */ + unsigned count = (rs->inst_count & R300_RS_INST_COUNT_MASK) + 1; CS_LOCALS(r300); DBG(r300, DBG_DRAW, "r300: RS emit:\n"); - BEGIN_CS(21); + BEGIN_CS(5 + count*2); if (r300screen->caps->is_r500) { - OUT_CS_REG_SEQ(R500_RS_IP_0, 8); + OUT_CS_REG_SEQ(R500_RS_IP_0, count); } else { - OUT_CS_REG_SEQ(R300_RS_IP_0, 8); + OUT_CS_REG_SEQ(R300_RS_IP_0, count); } - for (i = 0; i < 8; i++) { + for (i = 0; i < count; i++) { OUT_CS(rs->ip[i]); DBG(r300, DBG_DRAW, " : ip %d: 0x%08x\n", i, rs->ip[i]); } @@ -656,11 +651,11 @@ void r300_emit_rs_block_state(struct r300_context* r300, void* state) OUT_CS(rs->inst_count); if (r300screen->caps->is_r500) { - OUT_CS_REG_SEQ(R500_RS_INST_0, 8); + OUT_CS_REG_SEQ(R500_RS_INST_0, count); } else { - OUT_CS_REG_SEQ(R300_RS_INST_0, 8); + OUT_CS_REG_SEQ(R300_RS_INST_0, count); } - for (i = 0; i < 8; i++) { + for (i = 0; i < count; i++) { OUT_CS(rs->inst[i]); DBG(r300, DBG_DRAW, " : inst %d: 0x%08x\n", i, rs->inst[i]); } @@ -1153,14 +1148,15 @@ void r300_emit_dirty_state(struct r300_context* r300) for (i = 0; i < MIN2(r300->sampler_count, r300->texture_count); i++) { if (r300->dirty_state & ((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i))) { - if (r300->textures[i]) + if (r300->textures[i]) { r300_emit_texture(r300, r300->sampler_states[i], r300->textures[i], i); + dirty_tex |= r300->dirty_state & (R300_NEW_TEXTURE << i); + } r300->dirty_state &= ~((R300_NEW_SAMPLER << i) | (R300_NEW_TEXTURE << i)); - dirty_tex++; } } r300->dirty_state &= ~(R300_ANY_NEW_SAMPLERS | R300_ANY_NEW_TEXTURES); diff --git a/src/gallium/drivers/r300/r300_reg.h b/src/gallium/drivers/r300/r300_reg.h index 361813891f..a049da69e2 100644 --- a/src/gallium/drivers/r300/r300_reg.h +++ b/src/gallium/drivers/r300/r300_reg.h @@ -244,6 +244,9 @@ USE OR OTHER DEALINGS IN THE SOFTWARE. # define R300_DATA_TYPE_SHORT_4 7 # define R300_DATA_TYPE_VECTOR_3_TTT 8 # define R300_DATA_TYPE_VECTOR_3_EET 9 +# define R300_DATA_TYPE_FLOAT_8 10 +# define R300_DATA_TYPE_FLT16_2 11 +# define R300_DATA_TYPE_FLT16_4 12 # define R300_SKIP_DWORDS_SHIFT 4 # define R300_DST_VEC_LOC_SHIFT 8 # define R300_LAST_VEC (1 << 13) diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c index 13cd04a80c..b892c084c0 100644 --- a/src/gallium/drivers/r300/r300_screen.c +++ b/src/gallium/drivers/r300/r300_screen.c @@ -152,12 +152,12 @@ static int r300_get_param(struct pipe_screen* pscreen, int param) } else { return 0; } + case PIPE_CAP_MAX_CONST_BUFFERS: + return 1; + case PIPE_CAP_MAX_CONST_BUFFER_SIZE: + return 256; case PIPE_CAP_INDEP_BLEND_ENABLE: - if (r300screen->caps->is_r500) { - return 1; - } else { - return 0; - } + return 0; case PIPE_CAP_INDEP_BLEND_FUNC: return 0; case PIPE_CAP_TGSI_FS_COORD_ORIGIN_UPPER_LEFT: @@ -220,9 +220,6 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, switch (format) { /* Supported formats. */ /* Colorbuffer */ - case PIPE_FORMAT_A4R4G4B4_UNORM: - case PIPE_FORMAT_R5G6B5_UNORM: - case PIPE_FORMAT_A1R5G5B5_UNORM: case PIPE_FORMAT_A8_UNORM: case PIPE_FORMAT_L8_UNORM: retval = usage & @@ -246,6 +243,9 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, break; /* Colorbuffer or texture */ + case PIPE_FORMAT_R5G6B5_UNORM: + case PIPE_FORMAT_A1R5G5B5_UNORM: + case PIPE_FORMAT_A4R4G4B4_UNORM: case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_X8R8G8B8_UNORM: case PIPE_FORMAT_R8G8B8A8_UNORM: @@ -281,7 +281,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, case PIPE_FORMAT_X8Z24_UNORM: SCREEN_DBG(r300_screen(screen), DBG_TEX, "r300: Note: Got unsupported format: %s in %s\n", - pf_name(format), __FUNCTION__); + util_format_name(format), __FUNCTION__); return FALSE; /* XXX Add all remaining gallium-supported formats, @@ -290,7 +290,7 @@ static boolean r300_is_format_supported(struct pipe_screen* screen, default: /* Unknown format... */ debug_printf("r300: Warning: Got unknown format: %s in %s\n", - pf_name(format), __FUNCTION__); + util_format_name(format), __FUNCTION__); break; } diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c index 99ecae9f5f..34bf81c193 100644 --- a/src/gallium/drivers/r300/r300_state.c +++ b/src/gallium/drivers/r300/r300_state.c @@ -38,6 +38,8 @@ #include "r300_fs.h" #include "r300_vs.h" +#include "radeon_winsys.h" + /* r300_state: Functions used to intialize state context by translating * Gallium state objects into semi-native r300 state objects. */ @@ -425,7 +427,7 @@ static void* (r300_translate_stencil_op(state->stencil[0].zfail_op) << R300_S_FRONT_ZFAIL_OP_SHIFT); - dsa->stencil_ref_mask = (state->stencil[0].ref_value) | + dsa->stencil_ref_mask = (state->stencil[0].valuemask << R300_STENCILMASK_SHIFT) | (state->stencil[0].writemask << R300_STENCILWRITEMASK_SHIFT); @@ -444,7 +446,7 @@ static void* if (caps->is_r500) { dsa->z_buffer_control |= R500_STENCIL_REFMASK_FRONT_BACK; - dsa->stencil_ref_bf = (state->stencil[1].ref_value) | + dsa->stencil_ref_bf = (state->stencil[1].valuemask << R300_STENCILMASK_SHIFT) | (state->stencil[1].writemask << @@ -488,6 +490,77 @@ static void r300_delete_dsa_state(struct pipe_context* pipe, FREE(state); } +static void r300_set_stencil_ref(struct pipe_context* pipe, + const struct pipe_stencil_ref* sr) +{ + struct r300_context* r300 = r300_context(pipe); + r300->stencil_ref = *sr; + r300->dsa_state.dirty = TRUE; +} + +/* This switcheroo is needed just because of goddamned MACRO_SWITCH. */ +static void r300_fb_update_tiling_flags(struct r300_context *r300, + const struct pipe_framebuffer_state *old_state, + const struct pipe_framebuffer_state *new_state) +{ + struct r300_texture *tex; + unsigned i, j, level; + + /* Reset tiling flags for old surfaces to default values. */ + for (i = 0; i < old_state->nr_cbufs; i++) { + for (j = 0; j < new_state->nr_cbufs; j++) { + if (old_state->cbufs[i]->texture == new_state->cbufs[j]->texture) { + break; + } + } + /* If not binding the surface again... */ + if (j != new_state->nr_cbufs) { + continue; + } + + tex = (struct r300_texture*)old_state->cbufs[i]->texture; + + if (tex) { + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + tex->pitch[0], + tex->microtile != 0, + tex->macrotile != 0); + } + } + if (old_state->zsbuf && + (!new_state->zsbuf || + old_state->zsbuf->texture != new_state->zsbuf->texture)) { + tex = (struct r300_texture*)old_state->zsbuf->texture; + + if (tex) { + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + tex->pitch[0], + tex->microtile != 0, + tex->macrotile != 0); + } + } + + /* Set tiling flags for new surfaces. */ + for (i = 0; i < new_state->nr_cbufs; i++) { + tex = (struct r300_texture*)new_state->cbufs[i]->texture; + level = new_state->cbufs[i]->level; + + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + tex->pitch[level], + tex->microtile != 0, + tex->mip_macrotile[level] != 0); + } + if (new_state->zsbuf) { + tex = (struct r300_texture*)new_state->zsbuf->texture; + level = new_state->zsbuf->level; + + r300->winsys->buffer_set_tiling(r300->winsys, tex->buffer, + tex->pitch[level], + tex->microtile != 0, + tex->mip_macrotile[level] != 0); + } +} + static void r300_set_framebuffer_state(struct pipe_context* pipe, const struct pipe_framebuffer_state* state) @@ -497,9 +570,6 @@ static void unsigned max_width, max_height; uint32_t zbuffer_bpp = 0; - r300->fb_state.size = (10 * state->nr_cbufs) + - (2 * (4 - state->nr_cbufs)) + - (state->zsbuf ? 10 : 0) + 6; if (state->nr_cbufs > 4) { debug_printf("r300: Implementation error: Too many MRTs in %s, " @@ -521,13 +591,17 @@ static void return; } + if (r300->draw) { draw_flush(r300->draw); } memcpy(r300->fb_state.state, state, sizeof(struct pipe_framebuffer_state)); - /* Don't rely on the order of states being set for the first time. */ + r300->fb_state.size = (10 * state->nr_cbufs) + (state->zsbuf ? 10 : 0) + 6; + + r300_fb_update_tiling_flags(r300, r300->fb_state.state, state); + /* XXX wait what */ r300->blend_state.dirty = TRUE; r300->dsa_state.dirty = TRUE; @@ -794,7 +868,7 @@ static void* sampler->filter0 |= r300_translate_tex_filters(state->min_img_filter, state->mag_img_filter, state->min_mip_filter, - state->max_anisotropy > 1.0); + state->max_anisotropy > 0); /* Unfortunately, r300-r500 don't support floating-point mipmap lods. */ /* We must pass these to the emit function to clamp them properly. */ @@ -1076,7 +1150,9 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, struct pipe_buffer *buf) { struct r300_context* r300 = r300_context(pipe); + struct r300_screen *r300screen = r300_screen(pipe->screen); void *mapped; + int max_size = 0; if (buf == NULL || buf->size == 0 || (mapped = pipe_buffer_map(pipe->screen, buf, PIPE_BUFFER_USAGE_CPU_READ)) == NULL) @@ -1086,6 +1162,33 @@ static void r300_set_constant_buffer(struct pipe_context *pipe, } assert((buf->size % 4 * sizeof(float)) == 0); + + /* Check the size of the constant buffer. */ + switch (shader) { + case PIPE_SHADER_VERTEX: + max_size = 256; + break; + case PIPE_SHADER_FRAGMENT: + if (r300screen->caps->is_r500) { + max_size = 256; + /* XXX Implement emission of r400's extended constant buffer. */ + /*} else if (r300screen->caps->is_r400) { + max_size = 64;*/ + } else { + max_size = 32; + } + break; + default: + assert(0); + } + + /* XXX Subtract immediates and RC_STATE_* variables. */ + if (buf->size > (sizeof(float) * 4 * max_size)) { + debug_printf("r300: Max size of the constant buffer is " + "%i*4 floats.\n", max_size); + abort(); + } + memcpy(r300->shader_constants[shader].constants, mapped, buf->size); r300->shader_constants[shader].count = buf->size / (4 * sizeof(float)); pipe_buffer_unmap(pipe->screen, buf); @@ -1112,6 +1215,8 @@ void r300_init_state_functions(struct r300_context* r300) r300->context.bind_depth_stencil_alpha_state = r300_bind_dsa_state; r300->context.delete_depth_stencil_alpha_state = r300_delete_dsa_state; + r300->context.set_stencil_ref = r300_set_stencil_ref; + r300->context.set_framebuffer_state = r300_set_framebuffer_state; r300->context.create_fs_state = r300_create_fs_state; diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c index bad9e76067..2cbce9210a 100644 --- a/src/gallium/drivers/r300/r300_state_derived.c +++ b/src/gallium/drivers/r300/r300_state_derived.c @@ -306,7 +306,7 @@ static void r300_update_rs_block(struct r300_context* r300, struct r300_shader_semantics* fs_inputs) { struct r300_rs_block rs = { { 0 } }; - int i, col_count = 0, tex_count = 0, fp_offset = 0; + int i, col_count = 0, tex_count = 0, fp_offset = 0, count; void (*rX00_rs_col)(struct r300_rs_block*, int, int, boolean); void (*rX00_rs_col_write)(struct r300_rs_block*, int, int); void (*rX00_rs_tex)(struct r300_rs_block*, int, int, boolean); @@ -410,11 +410,13 @@ static void r300_update_rs_block(struct r300_context* r300, rs.count = (tex_count*4) | (col_count << R300_IC_COUNT_SHIFT) | R300_HIRES_EN; - rs.inst_count = MAX3(col_count - 1, tex_count - 1, 0); + count = MAX3(col_count, tex_count, 1); + rs.inst_count = count - 1; /* Now, after all that, see if we actually need to update the state. */ if (memcmp(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block))) { memcpy(r300->rs_block_state.state, &rs, sizeof(struct r300_rs_block)); + r300->rs_block_state.size = 5 + count; r300->rs_block_state.dirty = TRUE; } } diff --git a/src/gallium/drivers/r300/r300_state_inlines.h b/src/gallium/drivers/r300/r300_state_inlines.h index 5df6815221..6ee6cd0e3f 100644 --- a/src/gallium/drivers/r300/r300_state_inlines.h +++ b/src/gallium/drivers/r300/r300_state_inlines.h @@ -312,15 +312,15 @@ static INLINE uint32_t r300_translate_tex_filters(int min, int mag, int mip, return retval; } -static INLINE uint32_t r300_anisotropy(float max_aniso) +static INLINE uint32_t r300_anisotropy(unsigned max_aniso) { - if (max_aniso >= 16.0f) { + if (max_aniso >= 16) { return R300_TX_MAX_ANISO_16_TO_1; - } else if (max_aniso >= 8.0f) { + } else if (max_aniso >= 8) { return R300_TX_MAX_ANISO_8_TO_1; - } else if (max_aniso >= 4.0f) { + } else if (max_aniso >= 4) { return R300_TX_MAX_ANISO_4_TO_1; - } else if (max_aniso >= 2.0f) { + } else if (max_aniso >= 2) { return R300_TX_MAX_ANISO_2_TO_1; } else { return R300_TX_MAX_ANISO_1_TO_1; @@ -367,7 +367,7 @@ static INLINE uint32_t r300_translate_colorformat(enum pipe_format format) default: debug_printf("r300: Implementation error: " "Got unsupported color format %s in %s\n", - pf_name(format), __FUNCTION__); + util_format_name(format), __FUNCTION__); assert(0); break; } @@ -389,7 +389,7 @@ static INLINE uint32_t r300_translate_zsformat(enum pipe_format format) default: debug_printf("r300: Implementation error: " "Got unsupported ZS format %s in %s\n", - pf_name(format), __FUNCTION__); + util_format_name(format), __FUNCTION__); assert(0); break; } @@ -403,10 +403,14 @@ static INLINE uint32_t r300_translate_zsformat(enum pipe_format format) static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) { switch (format) { + case PIPE_FORMAT_R5G6B5_UNORM: + /* C_5_6_5 is missing in US_OUT_FMT, but C4_8 works just fine. */ + case PIPE_FORMAT_A1R5G5B5_UNORM: + /* C_1_5_5_5 is missing in US_OUT_FMT, but C4_8 works just fine. */ + case PIPE_FORMAT_A4R4G4B4_UNORM: + /* C4_4 is missing in US_OUT_FMT, but C4_8 works just fine. */ case PIPE_FORMAT_A8R8G8B8_UNORM: case PIPE_FORMAT_X8R8G8B8_UNORM: - /* XXX */ - case PIPE_FORMAT_Z24S8_UNORM: return R300_US_OUT_FMT_C4_8 | R300_C0_SEL_B | R300_C1_SEL_G | R300_C2_SEL_R | R300_C3_SEL_A; @@ -428,7 +432,7 @@ static INLINE uint32_t r300_translate_out_fmt(enum pipe_format format) default: debug_printf("r300: Implementation error: " "Got unsupported output format %s in %s\n", - pf_name(format), __FUNCTION__); + util_format_name(format), __FUNCTION__); assert(0); return R300_US_OUT_FMT_UNUSED; } @@ -494,7 +498,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { if (desc->layout != UTIL_FORMAT_LAYOUT_ARITH && desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) { - debug_printf("r300: Bad format %s in %s:%d\n", pf_name(format), + debug_printf("r300: Bad format %s in %s:%d\n", util_format_name(format), __FUNCTION__, __LINE__); assert(0); } @@ -503,12 +507,20 @@ r300_translate_vertex_data_type(enum pipe_format format) { /* Half-floats, floats, doubles */ case UTIL_FORMAT_TYPE_FLOAT: switch (util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)) { + case 16: + /* XXX Supported only on RV350 and later. */ + if (components > 2) { + result = R300_DATA_TYPE_FLT16_4; + } else { + result = R300_DATA_TYPE_FLT16_2; + } + break; case 32: result = R300_DATA_TYPE_FLOAT_1 + (components - 1); break; default: debug_printf("r300: Bad format %s in %s:%d\n", - pf_name(format), __FUNCTION__, __LINE__); + util_format_name(format), __FUNCTION__, __LINE__); assert(0); } break; @@ -529,7 +541,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { break; default: debug_printf("r300: Bad format %s in %s:%d\n", - pf_name(format), __FUNCTION__, __LINE__); + util_format_name(format), __FUNCTION__, __LINE__); debug_printf("r300: util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0) == %d\n", util_format_get_component_bits(format, UTIL_FORMAT_COLORSPACE_RGB, 0)); assert(0); @@ -537,7 +549,7 @@ r300_translate_vertex_data_type(enum pipe_format format) { break; default: debug_printf("r300: Bad format %s in %s:%d\n", - pf_name(format), __FUNCTION__, __LINE__); + util_format_name(format), __FUNCTION__, __LINE__); assert(0); } @@ -561,7 +573,7 @@ r300_translate_vertex_data_swizzle(enum pipe_format format) { if (desc->layout != UTIL_FORMAT_LAYOUT_ARITH && desc->layout != UTIL_FORMAT_LAYOUT_ARRAY) { debug_printf("r300: Bad format %s in %s:%d\n", - pf_name(format), __FUNCTION__, __LINE__); + util_format_name(format), __FUNCTION__, __LINE__); return 0; } diff --git a/src/gallium/drivers/r300/r300_texture.c b/src/gallium/drivers/r300/r300_texture.c index 417a57384c..34a49bec34 100644 --- a/src/gallium/drivers/r300/r300_texture.c +++ b/src/gallium/drivers/r300/r300_texture.c @@ -85,6 +85,20 @@ static void r300_setup_texture_state(struct r300_screen* screen, struct r300_tex pt->width0, pt->height0, pt->last_level); } +void r300_texture_reinterpret_format(struct pipe_screen *screen, + struct pipe_texture *tex, + enum pipe_format new_format) +{ + struct r300_screen *r300screen = r300_screen(screen); + + SCREEN_DBG(r300screen, DBG_TEX, "r300: Reinterpreting format: %s -> %s\n", + util_format_name(tex->format), util_format_name(new_format)); + + tex->format = new_format; + + r300_setup_texture_state(r300_screen(screen), (struct r300_texture*)tex); +} + unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, unsigned zslice, unsigned face) { @@ -109,18 +123,40 @@ unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, * Return the width (dim==TILE_WIDTH) or height (dim==TILE_HEIGHT) of one tile * of the given texture. */ -static unsigned r300_texture_get_tile_size(struct r300_texture* tex, int dim) +static unsigned r300_texture_get_tile_size(struct r300_texture* tex, + int dim, boolean macrotile) { unsigned pixsize, tile_size; pixsize = util_format_get_blocksize(tex->tex.format); - tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim] * - (tex->macrotile == R300_BUFFER_TILED ? 8 : 1); + tile_size = microblock_table[util_logbase2(pixsize)][tex->microtile][dim]; + + if (macrotile) { + tile_size *= 8; + } assert(tile_size); return tile_size; } +/* Return true if macrotiling should be enabled on the miplevel. */ +static boolean r300_texture_macro_switch(struct r300_texture *tex, + unsigned level, + boolean rv350_mode) +{ + unsigned tile_width, width; + + tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, TRUE); + width = u_minify(tex->tex.width0, level); + + /* See TX_FILTER1_n.MACRO_SWITCH. */ + if (rv350_mode) { + return width >= tile_width; + } else { + return width > tile_width; + } +} + /** * Return the stride, in bytes, of the texture images of the given texture * at the given level. @@ -143,8 +179,10 @@ unsigned r300_texture_get_stride(struct r300_screen* screen, width = u_minify(tex->tex.width0, level); if (!util_format_is_compressed(tex->tex.format)) { - tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH); + tile_width = r300_texture_get_tile_size(tex, TILE_WIDTH, + tex->mip_macrotile[level]); width = align(width, tile_width); + return util_format_get_stride(tex->tex.format, width); } else { return align(util_format_get_stride(tex->tex.format, width), 32); @@ -159,7 +197,8 @@ static unsigned r300_texture_get_nblocksy(struct r300_texture* tex, height = u_minify(tex->tex.height0, level); if (!util_format_is_compressed(tex->tex.format)) { - tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT); + tile_height = r300_texture_get_tile_size(tex, TILE_HEIGHT, + tex->mip_macrotile[level]); height = align(height, tile_height); } @@ -171,11 +210,17 @@ static void r300_setup_miptree(struct r300_screen* screen, { struct pipe_texture* base = &tex->tex; unsigned stride, size, layer_size, nblocksy, i; + boolean rv350_mode = screen->caps->family >= CHIP_FAMILY_RV350; SCREEN_DBG(screen, DBG_TEX, "r300: Making miptree for texture, format %s\n", - pf_name(base->format)); + util_format_name(base->format)); for (i = 0; i <= base->last_level; i++) { + /* Let's see if this miplevel can be macrotiled. */ + tex->mip_macrotile[i] = (tex->macrotile == R300_BUFFER_TILED && + r300_texture_macro_switch(tex, i, rv350_mode)) ? + R300_BUFFER_TILED : R300_BUFFER_LINEAR; + stride = r300_texture_get_stride(screen, tex, i); nblocksy = r300_texture_get_nblocksy(tex, i); layer_size = stride * nblocksy; @@ -185,15 +230,16 @@ static void r300_setup_miptree(struct r300_screen* screen, else size = layer_size * u_minify(base->depth0, i); - tex->offset[i] = align(tex->size, 32); + tex->offset[i] = tex->size; tex->size = tex->offset[i] + size; tex->layer_size[i] = layer_size; tex->pitch[i] = stride / util_format_get_blocksize(base->format); SCREEN_DBG(screen, DBG_TEX, "r300: Texture miptree: Level %d " - "(%dx%dx%d px, pitch %d bytes) %d bytes total\n", + "(%dx%dx%d px, pitch %d bytes) %d bytes total, macrotiled %s\n", i, u_minify(base->width0, i), u_minify(base->height0, i), - u_minify(base->depth0, i), stride, tex->size); + u_minify(base->depth0, i), stride, tex->size, + tex->mip_macrotile[i] ? "TRUE" : "FALSE"); } } diff --git a/src/gallium/drivers/r300/r300_texture.h b/src/gallium/drivers/r300/r300_texture.h index 961bdcc5b3..b9c3ab8093 100644 --- a/src/gallium/drivers/r300/r300_texture.h +++ b/src/gallium/drivers/r300/r300_texture.h @@ -24,6 +24,7 @@ #define R300_TEXTURE_H #include "pipe/p_video_state.h" +#include "util/u_format.h" #include "r300_reg.h" @@ -37,6 +38,10 @@ unsigned r300_texture_get_stride(struct r300_screen* screen, unsigned r300_texture_get_offset(struct r300_texture* tex, unsigned level, unsigned zslice, unsigned face); +void r300_texture_reinterpret_format(struct pipe_screen *screen, + struct pipe_texture *tex, + enum pipe_format new_format); + /* Translate a pipe_format into a useful texture format for sampling. * * R300_EASY_TX_FORMAT swizzles the texture. @@ -59,12 +64,20 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format) return R300_EASY_TX_FORMAT(X, X, X, ONE, X8) | R300_TX_FORMAT_GAMMA; /* X16 */ + case PIPE_FORMAT_A4R4G4B4_UNORM: + return R300_EASY_TX_FORMAT(X, Y, Z, W, W4Z4Y4X4); case PIPE_FORMAT_R16_UNORM: case PIPE_FORMAT_Z16_UNORM: return R300_EASY_TX_FORMAT(X, X, X, X, X16); case PIPE_FORMAT_R16_SNORM: return R300_EASY_TX_FORMAT(X, X, X, X, X16) | R300_TX_FORMAT_SIGNED; + /* Z5Y6X5 */ + case PIPE_FORMAT_R5G6B5_UNORM: + return R300_EASY_TX_FORMAT(X, Y, Z, ONE, Z5Y6X5); + /* W1Z5Y5X5*/ + case PIPE_FORMAT_A1R5G5B5_UNORM: + return R300_EASY_TX_FORMAT(X, Y, Z, W, W1Z5Y5X5); /* Y8X8 */ case PIPE_FORMAT_A8L8_UNORM: return R300_EASY_TX_FORMAT(X, X, X, Y, Y8X8); @@ -109,7 +122,7 @@ static INLINE uint32_t r300_translate_texformat(enum pipe_format format) default: debug_printf("r300: Implementation error: " "Got unsupported texture format %s in %s\n", - pf_name(format), __FUNCTION__); + util_format_name(format), __FUNCTION__); assert(0); break; } diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h index f4a8ae120c..40fb8a95ca 100644 --- a/src/gallium/drivers/r300/r300_winsys.h +++ b/src/gallium/drivers/r300/r300_winsys.h @@ -33,9 +33,8 @@ extern "C" { #include "pipe/p_defines.h" #include "pipe/p_state.h" -#include "util/u_simple_screen.h" -#include "radeon_winsys.h" +struct radeon_winsys; /* Creates a new r300 screen. */ struct pipe_screen* r300_create_screen(struct radeon_winsys* radeon_winsys); diff --git a/src/gallium/drivers/softpipe/sp_context.c b/src/gallium/drivers/softpipe/sp_context.c index 2b22ce256e..ddc35bcd62 100644 --- a/src/gallium/drivers/softpipe/sp_context.c +++ b/src/gallium/drivers/softpipe/sp_context.c @@ -246,6 +246,7 @@ softpipe_create_context( struct pipe_screen *screen, softpipe->pipe.delete_gs_state = softpipe_delete_gs_state; softpipe->pipe.set_blend_color = softpipe_set_blend_color; + softpipe->pipe.set_stencil_ref = softpipe_set_stencil_ref; softpipe->pipe.set_clip_state = softpipe_set_clip_state; softpipe->pipe.set_constant_buffer = softpipe_set_constant_buffer; softpipe->pipe.set_framebuffer_state = softpipe_set_framebuffer_state; diff --git a/src/gallium/drivers/softpipe/sp_context.h b/src/gallium/drivers/softpipe/sp_context.h index 62f9e7aad3..95def72c54 100644 --- a/src/gallium/drivers/softpipe/sp_context.h +++ b/src/gallium/drivers/softpipe/sp_context.h @@ -62,6 +62,7 @@ struct softpipe_context { /** Other rendering state */ struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; struct pipe_buffer *constants[PIPE_SHADER_TYPES][PIPE_MAX_CONSTANT_BUFFERS]; struct pipe_framebuffer_state framebuffer; diff --git a/src/gallium/drivers/softpipe/sp_quad_depth_test.c b/src/gallium/drivers/softpipe/sp_quad_depth_test.c index a981775cbd..499eebd671 100644 --- a/src/gallium/drivers/softpipe/sp_quad_depth_test.c +++ b/src/gallium/drivers/softpipe/sp_quad_depth_test.c @@ -519,7 +519,7 @@ depth_stencil_test_quad(struct quad_stage *qs, failOp = softpipe->depth_stencil->stencil[face].fail_op; zFailOp = softpipe->depth_stencil->stencil[face].zfail_op; zPassOp = softpipe->depth_stencil->stencil[face].zpass_op; - ref = softpipe->depth_stencil->stencil[face].ref_value; + ref = softpipe->stencil_ref.ref_value[face]; wrtMask = softpipe->depth_stencil->stencil[face].writemask; valMask = softpipe->depth_stencil->stencil[face].valuemask; diff --git a/src/gallium/drivers/softpipe/sp_state.h b/src/gallium/drivers/softpipe/sp_state.h index a83cae7361..4370bbeaee 100644 --- a/src/gallium/drivers/softpipe/sp_state.h +++ b/src/gallium/drivers/softpipe/sp_state.h @@ -132,13 +132,16 @@ void softpipe_bind_rasterizer_state(struct pipe_context *, void *); void softpipe_delete_rasterizer_state(struct pipe_context *, void *); void softpipe_set_framebuffer_state( struct pipe_context *, - const struct pipe_framebuffer_state * ); + const struct pipe_framebuffer_state * ); void softpipe_set_blend_color( struct pipe_context *pipe, const struct pipe_blend_color *blend_color ); +void softpipe_set_stencil_ref( struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref ); + void softpipe_set_clip_state( struct pipe_context *, - const struct pipe_clip_state * ); + const struct pipe_clip_state * ); void softpipe_set_constant_buffer(struct pipe_context *, uint shader, uint index, diff --git a/src/gallium/drivers/softpipe/sp_state_blend.c b/src/gallium/drivers/softpipe/sp_state_blend.c index 95ab323433..c63a49e90b 100644 --- a/src/gallium/drivers/softpipe/sp_state_blend.c +++ b/src/gallium/drivers/softpipe/sp_state_blend.c @@ -61,7 +61,7 @@ void softpipe_delete_blend_state(struct pipe_context *pipe, void softpipe_set_blend_color( struct pipe_context *pipe, - const struct pipe_blend_color *blend_color ) + const struct pipe_blend_color *blend_color ) { struct softpipe_context *softpipe = softpipe_context(pipe); @@ -80,7 +80,7 @@ void softpipe_set_blend_color( struct pipe_context *pipe, void * softpipe_create_depth_stencil_state(struct pipe_context *pipe, - const struct pipe_depth_stencil_alpha_state *depth_stencil) + const struct pipe_depth_stencil_alpha_state *depth_stencil) { return mem_dup(depth_stencil, sizeof(*depth_stencil)); } @@ -101,3 +101,13 @@ softpipe_delete_depth_stencil_state(struct pipe_context *pipe, void *depth) { FREE( depth ); } + +void softpipe_set_stencil_ref( struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref ) +{ + struct softpipe_context *softpipe = softpipe_context(pipe); + + softpipe->stencil_ref = *stencil_ref; + + softpipe->dirty |= SP_NEW_DEPTH_STENCIL_ALPHA; +} diff --git a/src/gallium/drivers/softpipe/sp_tex_sample.c b/src/gallium/drivers/softpipe/sp_tex_sample.c index 473ec3e150..ecd6b39863 100644 --- a/src/gallium/drivers/softpipe/sp_tex_sample.c +++ b/src/gallium/drivers/softpipe/sp_tex_sample.c @@ -1327,6 +1327,11 @@ mip_filter_linear(struct tgsi_sampler *tgsi_sampler, } +/** + * Compute nearest mipmap level from texcoords. + * Then sample the texture level for four elements of a quad. + * \param c0 the LOD bias factors, or absolute LODs (depending on control) + */ static void mip_filter_nearest(struct tgsi_sampler *tgsi_sampler, const float s[QUAD_SIZE], @@ -1563,8 +1568,8 @@ sample_compare(struct tgsi_sampler *tgsi_sampler, /** - * Compute which cube face is referenced by each texcoord and put that - * info into the sampler faces[] array. Then sample the cube faces + * Use 3D texcoords to choose a cube face, then sample the 2D cube faces. + * Put face info into the sampler faces[] array. */ static void sample_cube(struct tgsi_sampler *tgsi_sampler, @@ -1578,11 +1583,12 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, struct sp_sampler_varient *samp = sp_sampler_varient(tgsi_sampler); unsigned j; float ssss[4], tttt[4]; + unsigned face; /* major axis - direction target sc tc ma - ---------- ------------------------------- --- --- --- + direction target sc tc ma + ---------- ------------------------------- --- --- --- +rx TEXTURE_CUBE_MAP_POSITIVE_X_EXT -rz -ry rx -rx TEXTURE_CUBE_MAP_NEGATIVE_X_EXT +rz -ry rx +ry TEXTURE_CUBE_MAP_POSITIVE_Y_EXT +rx +rz ry @@ -1590,56 +1596,96 @@ sample_cube(struct tgsi_sampler *tgsi_sampler, +rz TEXTURE_CUBE_MAP_POSITIVE_Z_EXT +rx -ry rz -rz TEXTURE_CUBE_MAP_NEGATIVE_Z_EXT -rx -ry rz */ - for (j = 0; j < QUAD_SIZE; j++) { - float rx = s[j]; - float ry = t[j]; - float rz = p[j]; + + /* First choose the cube face. + * Use the same cube face for all four pixels in the quad. + * + * This isn't ideal, but if we want to use a different cube face + * per pixel in the quad, we'd have to also compute the per-face + * LOD here too. That's because the four post-face-selection + * texcoords are no longer related to each other (they're + * per-face!) so we can't use subtraction to compute the partial + * deriviates to compute the LOD. Doing so (near cube edges + * anyway) gives us pretty much random values. + */ + { + /* use the average of the four pixel's texcoords to choose the face */ + const float rx = 0.25 * (s[0] + s[1] + s[2] + s[3]); + const float ry = 0.25 * (t[0] + t[1] + t[2] + t[3]); + const float rz = 0.25 * (p[0] + p[1] + p[2] + p[3]); const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); - unsigned face; - float sc, tc, ma; if (arx >= ary && arx >= arz) { if (rx >= 0.0F) { face = PIPE_TEX_FACE_POS_X; - sc = -rz; - tc = -ry; - ma = arx; } else { face = PIPE_TEX_FACE_NEG_X; - sc = rz; - tc = -ry; - ma = arx; } } else if (ary >= arx && ary >= arz) { if (ry >= 0.0F) { face = PIPE_TEX_FACE_POS_Y; - sc = rx; - tc = rz; - ma = ary; } else { face = PIPE_TEX_FACE_NEG_Y; - sc = rx; - tc = -rz; - ma = ary; } } else { if (rz > 0.0F) { face = PIPE_TEX_FACE_POS_Z; - sc = rx; - tc = -ry; - ma = arz; } else { face = PIPE_TEX_FACE_NEG_Z; - sc = -rx; - tc = -ry; - ma = arz; } } + } + + /* Now compute the 2D _face_ texture coords from the + * 3D _cube_ texture coords. + */ + for (j = 0; j < QUAD_SIZE; j++) { + const float rx = s[j], ry = t[j], rz = p[j]; + const float arx = fabsf(rx), ary = fabsf(ry), arz = fabsf(rz); + float sc, tc, ma; + + switch (face) { + case PIPE_TEX_FACE_POS_X: + sc = -rz; + tc = -ry; + ma = arx; + break; + case PIPE_TEX_FACE_NEG_X: + sc = rz; + tc = -ry; + ma = arx; + break; + case PIPE_TEX_FACE_POS_Y: + sc = rx; + tc = rz; + ma = ary; + break; + case PIPE_TEX_FACE_NEG_Y: + sc = rx; + tc = -rz; + ma = ary; + break; + case PIPE_TEX_FACE_POS_Z: + sc = rx; + tc = -ry; + ma = arz; + break; + case PIPE_TEX_FACE_NEG_Z: + sc = -rx; + tc = -ry; + ma = arz; + break; + default: + assert(0 && "bad cube face"); + sc = 0.0F; + tc = 0.0F; + ma = 0.0F; + } { const float ima = 1.0 / ma; diff --git a/src/gallium/drivers/softpipe/sp_video_context.c b/src/gallium/drivers/softpipe/sp_video_context.c index d8b5b31e95..7a3a636167 100644 --- a/src/gallium/drivers/softpipe/sp_video_context.c +++ b/src/gallium/drivers/softpipe/sp_video_context.c @@ -209,7 +209,6 @@ init_pipe_state(struct sp_mpeg12_context *ctx) dsa.stencil[i].fail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[i].zpass_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[i].zfail_op = PIPE_STENCIL_OP_KEEP; - dsa.stencil[i].ref_value = 0; dsa.stencil[i].valuemask = 0; dsa.stencil[i].writemask = 0; } diff --git a/src/gallium/drivers/svga/svga_context.h b/src/gallium/drivers/svga/svga_context.h index f9a641c6df..03302e2a6e 100644 --- a/src/gallium/drivers/svga/svga_context.h +++ b/src/gallium/drivers/svga/svga_context.h @@ -116,7 +116,6 @@ struct svga_depth_stencil_state { /* SVGA3D has one ref/mask/writemask triple shared between front & * back face stencil. We really need two: */ - unsigned stencil_ref:8; unsigned stencil_mask:8; unsigned stencil_writemask:8; @@ -199,6 +198,7 @@ struct svga_state struct pipe_poly_stipple poly_stipple; struct pipe_scissor_state scissor; struct pipe_blend_color blend_color; + struct pipe_stencil_ref stencil_ref; struct pipe_clip_state clip; struct pipe_viewport_state viewport; @@ -376,6 +376,7 @@ struct svga_context #define SVGA_NEW_VS_RESULT 0x1000000 #define SVGA_NEW_ZERO_STRIDE 0x2000000 #define SVGA_NEW_TEXTURE_FLAGS 0x4000000 +#define SVGA_NEW_STENCIL_REF 0x8000000 diff --git a/src/gallium/drivers/svga/svga_draw.c b/src/gallium/drivers/svga/svga_draw.c index f4d2d8992c..8b7ca2e112 100644 --- a/src/gallium/drivers/svga/svga_draw.c +++ b/src/gallium/drivers/svga/svga_draw.c @@ -253,7 +253,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, assert(index_bias >= 0); assert(min_index <= max_index); assert(offset + index_bias*stride < size); - assert(offset + (index_bias + min_index)*stride < size); + if (min_index != ~0) { + assert(offset + (index_bias + min_index) * stride < size); + } switch (hwtnl->cmd.vdecl[i].identity.type) { case SVGA3D_DECLTYPE_FLOAT1: @@ -314,7 +316,9 @@ enum pipe_error svga_hwtnl_prim( struct svga_hwtnl *hwtnl, } assert(!stride || width <= stride); - assert(offset + (index_bias + max_index)*stride + width <= size); + if (max_index != ~0) { + assert(offset + (index_bias + max_index) * stride + width <= size); + } } assert(range->indexWidth == range->indexArray.stride); diff --git a/src/gallium/drivers/svga/svga_pipe_blend.c b/src/gallium/drivers/svga/svga_pipe_blend.c index 9dd6fb068c..b60117f090 100644 --- a/src/gallium/drivers/svga/svga_pipe_blend.c +++ b/src/gallium/drivers/svga/svga_pipe_blend.c @@ -228,7 +228,7 @@ static void svga_set_blend_color( struct pipe_context *pipe, svga->curr.blend_color = *blend_color; - svga->dirty |= SVGA_NEW_BLEND; + svga->dirty |= SVGA_NEW_BLEND_COLOR; } diff --git a/src/gallium/drivers/svga/svga_pipe_depthstencil.c b/src/gallium/drivers/svga/svga_pipe_depthstencil.c index 12bbd233a5..c317bec6d5 100644 --- a/src/gallium/drivers/svga/svga_pipe_depthstencil.c +++ b/src/gallium/drivers/svga/svga_pipe_depthstencil.c @@ -89,7 +89,6 @@ svga_create_depth_stencil_state(struct pipe_context *pipe, /* SVGA3D has one ref/mask/writemask triple shared between front & * back face stencil. We really need two: */ - ds->stencil_ref = templ->stencil[0].ref_value & 0xff; ds->stencil_mask = templ->stencil[0].valuemask & 0xff; ds->stencil_writemask = templ->stencil[0].writemask & 0xff; } @@ -102,7 +101,6 @@ svga_create_depth_stencil_state(struct pipe_context *pipe, ds->stencil[1].zfail = svga_translate_stencil_op(templ->stencil[1].zfail_op); ds->stencil[1].pass = svga_translate_stencil_op(templ->stencil[1].zpass_op); - ds->stencil_ref = templ->stencil[1].ref_value & 0xff; ds->stencil_mask = templ->stencil[1].valuemask & 0xff; ds->stencil_writemask = templ->stencil[1].writemask & 0xff; } @@ -139,12 +137,24 @@ static void svga_delete_depth_stencil_state(struct pipe_context *pipe, } +static void svga_set_stencil_ref( struct pipe_context *pipe, + const struct pipe_stencil_ref *stencil_ref ) +{ + struct svga_context *svga = svga_context(pipe); + + svga->curr.stencil_ref = *stencil_ref; + + svga->dirty |= SVGA_NEW_STENCIL_REF; +} + void svga_init_depth_stencil_functions( struct svga_context *svga ) { svga->pipe.create_depth_stencil_alpha_state = svga_create_depth_stencil_state; svga->pipe.bind_depth_stencil_alpha_state = svga_bind_depth_stencil_state; svga->pipe.delete_depth_stencil_alpha_state = svga_delete_depth_stencil_state; + + svga->pipe.set_stencil_ref = svga_set_stencil_ref; } diff --git a/src/gallium/drivers/svga/svga_pipe_sampler.c b/src/gallium/drivers/svga/svga_pipe_sampler.c index b70081343d..224c4f4c18 100644 --- a/src/gallium/drivers/svga/svga_pipe_sampler.c +++ b/src/gallium/drivers/svga/svga_pipe_sampler.c @@ -27,7 +27,6 @@ #include "pipe/p_defines.h" #include "util/u_math.h" #include "util/u_memory.h" -#include "util/u_pack_color.h" #include "tgsi/tgsi_parse.h" #include "svga_context.h" @@ -97,13 +96,12 @@ svga_create_sampler_state(struct pipe_context *pipe, { struct svga_context *svga = svga_context(pipe); struct svga_sampler_state *cso = CALLOC_STRUCT( svga_sampler_state ); - union util_color uc; cso->mipfilter = translate_mip_filter(sampler->min_mip_filter); cso->magfilter = translate_img_filter( sampler->mag_img_filter ); cso->minfilter = translate_img_filter( sampler->min_img_filter ); - cso->aniso_level = MAX2( (unsigned) sampler->max_anisotropy, 1 ); - if(cso->aniso_level != 1) + cso->aniso_level = MAX2( sampler->max_anisotropy, 1 ); + if(sampler->max_anisotropy) cso->magfilter = cso->minfilter = SVGA3D_TEX_FILTER_ANISOTROPIC; cso->lod_bias = sampler->lod_bias; cso->addressu = translate_wrap_mode(sampler->wrap_s); @@ -114,14 +112,12 @@ svga_create_sampler_state(struct pipe_context *pipe, cso->compare_func = sampler->compare_func; { - ubyte r = float_to_ubyte(sampler->border_color[0]); - ubyte g = float_to_ubyte(sampler->border_color[1]); - ubyte b = float_to_ubyte(sampler->border_color[2]); - ubyte a = float_to_ubyte(sampler->border_color[3]); - - util_pack_color_ub( r, g, b, a, - PIPE_FORMAT_B8G8R8A8_UNORM, &uc); - cso->bordercolor = uc.ui; + uint32 r = float_to_ubyte(sampler->border_color[0]); + uint32 g = float_to_ubyte(sampler->border_color[1]); + uint32 b = float_to_ubyte(sampler->border_color[2]); + uint32 a = float_to_ubyte(sampler->border_color[3]); + + cso->bordercolor = (a << 24) | (r << 16) | (g << 8) | b; } /* No SVGA3D support for: diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c index 735cdfdae9..414ac52e1f 100644 --- a/src/gallium/drivers/svga/svga_screen.c +++ b/src/gallium/drivers/svga/svga_screen.c @@ -104,7 +104,9 @@ svga_get_paramf(struct pipe_screen *screen, int param) return SVGA_MAX_POINTSIZE; case PIPE_CAP_MAX_TEXTURE_ANISOTROPY: - return 4.0; + if(!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_ANISOTROPY, &result)) + return 4.0; + return result.u; case PIPE_CAP_MAX_TEXTURE_LOD_BIAS: return 16.0; @@ -133,12 +135,33 @@ svga_get_paramf(struct pipe_screen *screen, int param) return 1; case PIPE_CAP_TEXTURE_SHADOW_MAP: return 1; + case PIPE_CAP_MAX_TEXTURE_2D_LEVELS: - return SVGA_MAX_TEXTURE_LEVELS; + { + unsigned levels = SVGA_MAX_TEXTURE_LEVELS; + if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_WIDTH, &result)) + levels = MIN2(util_logbase2(result.u) + 1, levels); + else + levels = 12 /* 2048x2048 */; + if (sws->get_cap(sws, SVGA3D_DEVCAP_MAX_TEXTURE_HEIGHT, &result)) + levels = MIN2(util_logbase2(result.u) + 1, levels); + else + levels = 12 /* 2048x2048 */; + return levels; + } + case PIPE_CAP_MAX_TEXTURE_3D_LEVELS: - return 8; /* max 128x128x128 */ + if (!sws->get_cap(sws, SVGA3D_DEVCAP_MAX_VOLUME_EXTENT, &result)) + return 8; /* max 128x128x128 */ + return MIN2(util_logbase2(result.u) + 1, SVGA_MAX_TEXTURE_LEVELS); + case PIPE_CAP_MAX_TEXTURE_CUBE_LEVELS: - return SVGA_MAX_TEXTURE_LEVELS; + /* + * No mechanism to query the host, and at least limited to 2048x2048 on + * certain hardware. + */ + return MIN2(screen->get_paramf(screen, PIPE_CAP_MAX_TEXTURE_2D_LEVELS), + 12.0 /* 2048x2048 */); case PIPE_CAP_TEXTURE_MIRROR_REPEAT: /* req. for GL 1.4 */ return 1; diff --git a/src/gallium/drivers/svga/svga_screen_texture.h b/src/gallium/drivers/svga/svga_screen_texture.h index 43853d48f8..24c1f78ca5 100644 --- a/src/gallium/drivers/svga/svga_screen_texture.h +++ b/src/gallium/drivers/svga/svga_screen_texture.h @@ -39,7 +39,7 @@ struct svga_winsys_surface; enum SVGA3dSurfaceFormat; -#define SVGA_MAX_TEXTURE_LEVELS 12 /* 2048x2048 */ +#define SVGA_MAX_TEXTURE_LEVELS 16 /** diff --git a/src/gallium/drivers/svga/svga_state_rss.c b/src/gallium/drivers/svga/svga_state_rss.c index 5ce9b4ef4f..107cc403b4 100644 --- a/src/gallium/drivers/svga/svga_state_rss.c +++ b/src/gallium/drivers/svga/svga_state_rss.c @@ -100,6 +100,17 @@ static int emit_rss( struct svga_context *svga, } } + if (dirty & SVGA_NEW_BLEND_COLOR) { + uint32 color; + uint32 r = float_to_ubyte(svga->curr.blend_color.color[0]); + uint32 g = float_to_ubyte(svga->curr.blend_color.color[1]); + uint32 b = float_to_ubyte(svga->curr.blend_color.color[2]); + uint32 a = float_to_ubyte(svga->curr.blend_color.color[3]); + + color = (a << 24) | (r << 16) | (g << 8) | b; + + EMIT_RS( svga, color, BLENDCOLOR, fail ); + } if (dirty & (SVGA_NEW_DEPTH_STENCIL | SVGA_NEW_RAST)) { const struct svga_depth_stencil_state *curr = svga->curr.depth; @@ -123,8 +134,7 @@ static int emit_rss( struct svga_context *svga, EMIT_RS( svga, curr->stencil[0].fail, STENCILFAIL, fail ); EMIT_RS( svga, curr->stencil[0].zfail, STENCILZFAIL, fail ); EMIT_RS( svga, curr->stencil[0].pass, STENCILPASS, fail ); - - EMIT_RS( svga, curr->stencil_ref, STENCILREF, fail ); + EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail ); EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail ); } @@ -160,7 +170,6 @@ static int emit_rss( struct svga_context *svga, EMIT_RS( svga, curr->stencil[ccw].zfail, CCWSTENCILZFAIL, fail ); EMIT_RS( svga, curr->stencil[ccw].pass, CCWSTENCILPASS, fail ); - EMIT_RS( svga, curr->stencil_ref, STENCILREF, fail ); EMIT_RS( svga, curr->stencil_mask, STENCILMASK, fail ); EMIT_RS( svga, curr->stencil_writemask, STENCILWRITEMASK, fail ); } @@ -178,6 +187,9 @@ static int emit_rss( struct svga_context *svga, } } + if (dirty & SVGA_NEW_STENCIL_REF) { + EMIT_RS( svga, svga->curr.stencil_ref.ref_value[0], STENCILREF, fail ); + } if (dirty & SVGA_NEW_RAST) { @@ -231,13 +243,10 @@ static int emit_rss( struct svga_context *svga, memcpy( rs, queue.rs, queue.rs_count * sizeof queue.rs[0]); - + SVGA_FIFOCommitAll( svga->swc ); } - /* Also blend color: - */ - return 0; fail: @@ -257,7 +266,9 @@ struct svga_tracked_state svga_hw_rss = "hw rss state", (SVGA_NEW_BLEND | + SVGA_NEW_BLEND_COLOR | SVGA_NEW_DEPTH_STENCIL | + SVGA_NEW_STENCIL_REF | SVGA_NEW_RAST | SVGA_NEW_FRAME_BUFFER | SVGA_NEW_NEED_PIPELINE), diff --git a/src/gallium/drivers/svga/svga_tgsi_insn.c b/src/gallium/drivers/svga/svga_tgsi_insn.c index be821e9821..6debd98b7a 100644 --- a/src/gallium/drivers/svga/svga_tgsi_insn.c +++ b/src/gallium/drivers/svga/svga_tgsi_insn.c @@ -525,6 +525,7 @@ static boolean emit_def_const( struct svga_shader_emitter *emit, break; default: assert(0); + opcode = inst_token( SVGA3DOP_NOP ); break; } diff --git a/src/gallium/drivers/svga/svgadump/svga_shader.h b/src/gallium/drivers/svga/svgadump/svga_shader.h index 9217af2dd9..5db64bf135 100644 --- a/src/gallium/drivers/svga/svgadump/svga_shader.h +++ b/src/gallium/drivers/svga/svgadump/svga_shader.h @@ -98,21 +98,33 @@ struct sh_defi #define PS_TEXTURETYPE_CUBE SVGA3DSAMP_CUBE #define PS_TEXTURETYPE_VOLUME SVGA3DSAMP_VOLUME -struct ps_sampleinfo +struct sh_sampleinfo { unsigned unused:27; unsigned texture_type:4; unsigned is_reg:1; }; -struct vs_semantic +struct sh_semantic { - unsigned usage:5; - unsigned unused1:11; + unsigned usage:4; + unsigned unused1:12; unsigned usage_index:4; - unsigned unused2:12; + unsigned unused2:11; + unsigned is_reg:1; }; +#define SH_WRITEMASK_0 0x1 +#define SH_WRITEMASK_1 0x2 +#define SH_WRITEMASK_2 0x4 +#define SH_WRITEMASK_3 0x8 +#define SH_WRITEMASK_ALL 0xf + +#define SH_DSTMOD_NONE 0x0 +#define SH_DSTMOD_SATURATE 0x1 +#define SH_DSTMOD_PARTIALPRECISION 0x2 +#define SH_DSTMOD_MSAMPCENTROID 0x4 + struct sh_dstreg { unsigned number:11; @@ -136,17 +148,12 @@ struct sh_dcl { struct sh_op op; union { - struct { - struct ps_sampleinfo sampleinfo; - } ps; - struct { - struct vs_semantic semantic; - } vs; + struct sh_sampleinfo sampleinfo; + struct sh_semantic semantic; } u; struct sh_dstreg reg; }; - struct sh_srcreg { unsigned number:11; diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c index 70e27d86d3..705ca29e8f 100644 --- a/src/gallium/drivers/svga/svgadump/svga_shader_dump.c +++ b/src/gallium/drivers/svga/svgadump/svga_shader_dump.c @@ -40,102 +40,139 @@ struct dump_info { - SVGA3dShaderVersion version; + uint32 version; boolean is_ps; + int indent; }; -static void dump_op( struct sh_op op, const char *mnemonic ) +#define DUMP_MAX_OP_SRC 4 + +struct dump_op { - assert( op.predicated == 0 ); - assert( op.is_reg == 0 ); + struct sh_op op; + struct sh_dstreg dst; + struct sh_srcreg dstind; + struct sh_srcreg src[DUMP_MAX_OP_SRC]; + struct sh_srcreg srcind[DUMP_MAX_OP_SRC]; + struct sh_srcreg p0; +}; - if (op.coissue) - _debug_printf( "+" ); - _debug_printf( "%s", mnemonic ); - switch (op.control) { - case 0: - break; - case SVGA3DOPCONT_PROJECT: - _debug_printf( "p" ); - break; - case SVGA3DOPCONT_BIAS: - _debug_printf( "b" ); - break; - default: - assert( 0 ); +static void +dump_indent(int indent) +{ + int i; + + for (i = 0; i < indent; ++i) { + _debug_printf(" "); } } - -static void dump_comp_op( struct sh_op op, const char *mnemonic ) +static void dump_op( struct sh_op op, const char *mnemonic ) { assert( op.is_reg == 0 ); + if (op.predicated) { + _debug_printf("(p0) "); + } if (op.coissue) _debug_printf( "+" ); _debug_printf( "%s", mnemonic ); - switch (op.control) { - case SVGA3DOPCOMP_RESERVED0: - break; - case SVGA3DOPCOMP_GT: - _debug_printf("_gt"); - break; - case SVGA3DOPCOMP_EQ: - _debug_printf("_eq"); - break; - case SVGA3DOPCOMP_GE: - _debug_printf("_ge"); - break; - case SVGA3DOPCOMP_LT: - _debug_printf("_lt"); - break; - case SVGA3DOPCOMPC_NE: - _debug_printf("_ne"); + + switch (op.opcode) { + case SVGA3DOP_TEX: + switch (op.control) { + case 0: + break; + case 1 /* PROJECT */: + _debug_printf("p"); + break; + case 2 /* BIAS */: + _debug_printf("b"); + break; + default: + assert(0); + } break; - case SVGA3DOPCOMP_LE: - _debug_printf("_le"); + + case SVGA3DOP_IFC: + case SVGA3DOP_BREAKC: + case SVGA3DOP_SETP: + switch (op.control) { + case SVGA3DOPCOMP_GT: + _debug_printf("_gt"); + break; + case SVGA3DOPCOMP_EQ: + _debug_printf("_eq"); + break; + case SVGA3DOPCOMP_GE: + _debug_printf("_ge"); + break; + case SVGA3DOPCOMP_LT: + _debug_printf("_lt"); + break; + case SVGA3DOPCOMPC_NE: + _debug_printf("_ne"); + break; + case SVGA3DOPCOMP_LE: + _debug_printf("_le"); + break; + default: + assert(0); + } break; - case SVGA3DOPCOMP_RESERVED1: + default: - assert( 0 ); + assert(op.control == 0); } } +static void +format_reg(const char *name, + const struct sh_reg reg, + const struct sh_srcreg *indreg) +{ + if (reg.relative) { + assert(indreg); + + if (sh_srcreg_type(*indreg) == SVGA3DREG_LOOP) { + _debug_printf("%s[aL+%u]", name, reg.number); + } else { + _debug_printf("%s[a%u.x+%u]", name, indreg->number, reg.number); + } + } else { + _debug_printf("%s%u", name, reg.number); + } +} static void dump_reg( struct sh_reg reg, struct sh_srcreg *indreg, const struct dump_info *di ) { - assert( sh_reg_type( reg ) == SVGA3DREG_CONST || reg.relative == 0 ); assert( reg.is_reg == 1 ); switch (sh_reg_type( reg )) { case SVGA3DREG_TEMP: - _debug_printf( "r%u", reg.number ); + format_reg("r", reg, NULL); break; case SVGA3DREG_INPUT: - _debug_printf( "v%u", reg.number ); + format_reg("v", reg, indreg); break; case SVGA3DREG_CONST: - if (reg.relative) { - if (sh_srcreg_type( *indreg ) == SVGA3DREG_LOOP) - _debug_printf( "c[aL+%u]", reg.number ); - else - _debug_printf( "c[a%u.x+%u]", indreg->number, reg.number ); - } - else - _debug_printf( "c%u", reg.number ); + format_reg("c", reg, indreg); break; case SVGA3DREG_ADDR: /* VS */ /* SVGA3DREG_TEXTURE */ /* PS */ - if (di->is_ps) - _debug_printf( "t%u", reg.number ); - else - _debug_printf( "a%u", reg.number ); + assert(!reg.relative); + if (di->is_ps) { + format_reg("t", reg, NULL); + } else { + format_reg("a", reg, NULL); + } break; case SVGA3DREG_RASTOUT: + assert(!reg.relative); switch (reg.number) { case 0 /*POSITION*/: _debug_printf( "oPos" ); @@ -154,64 +191,69 @@ static void dump_reg( struct sh_reg reg, struct sh_srcreg *indreg, const struct case SVGA3DREG_ATTROUT: assert( reg.number < 2 ); - _debug_printf( "oD%u", reg.number ); + format_reg("oD", reg, NULL); break; - case SVGA3DREG_TEXCRDOUT: - /* SVGA3DREG_OUTPUT */ - _debug_printf( "oT%u", reg.number ); + case SVGA3DREG_TEXCRDOUT: /* VS */ + /* SVGA3DREG_OUTPUT */ /* VS3.0+ */ + if (!di->is_ps && di->version >= SVGA3D_VS_30) { + format_reg("o", reg, indreg); + } else { + format_reg("oT", reg, NULL); + } break; case SVGA3DREG_COLOROUT: - _debug_printf( "oC%u", reg.number ); + format_reg("oC", reg, NULL); break; case SVGA3DREG_DEPTHOUT: - _debug_printf( "oD%u", reg.number ); + assert(!reg.relative); + assert(reg.number == 0); + _debug_printf("oDepth"); break; case SVGA3DREG_SAMPLER: - _debug_printf( "s%u", reg.number ); + format_reg("s", reg, NULL); break; case SVGA3DREG_CONSTBOOL: - assert( !reg.relative ); - _debug_printf( "b%u", reg.number ); + format_reg("b", reg, NULL); break; case SVGA3DREG_CONSTINT: - assert( !reg.relative ); - _debug_printf( "i%u", reg.number ); + format_reg("i", reg, NULL); break; case SVGA3DREG_LOOP: + assert(!reg.relative); assert( reg.number == 0 ); _debug_printf( "aL" ); break; case SVGA3DREG_MISCTYPE: + assert(!reg.relative); switch (reg.number) { case SVGA3DMISCREG_POSITION: - _debug_printf( "vPos" ); + _debug_printf("vPos"); break; case SVGA3DMISCREG_FACE: - _debug_printf( "vFace" ); + _debug_printf("vFace"); break; default: assert(0); - break; + _debug_printf("???"); } break; case SVGA3DREG_LABEL: - _debug_printf( "l%u", reg.number ); + format_reg("l", reg, NULL); break; case SVGA3DREG_PREDICATE: - _debug_printf( "p%u", reg.number ); + format_reg("p", reg, NULL); break; - default: assert( 0 ); _debug_printf( "???" ); @@ -233,8 +275,11 @@ static void dump_bdata( boolean bdata ) _debug_printf( bdata ? "TRUE" : "FALSE" ); } -static void dump_sampleinfo( struct ps_sampleinfo sampleinfo ) +static void +dump_sampleinfo(struct sh_sampleinfo sampleinfo) { + assert( sampleinfo.is_reg == 1 ); + switch (sampleinfo.texture_type) { case SVGA3DSAMP_2D: _debug_printf( "_2d" ); @@ -250,68 +295,72 @@ static void dump_sampleinfo( struct ps_sampleinfo sampleinfo ) } } - -static void dump_usageinfo( struct vs_semantic semantic ) +static void +dump_semantic(uint usage, + uint usage_index) { - switch (semantic.usage) { + switch (usage) { case SVGA3D_DECLUSAGE_POSITION: - _debug_printf("_position" ); + _debug_printf("_position"); break; case SVGA3D_DECLUSAGE_BLENDWEIGHT: - _debug_printf("_blendweight" ); + _debug_printf("_blendweight"); break; case SVGA3D_DECLUSAGE_BLENDINDICES: - _debug_printf("_blendindices" ); + _debug_printf("_blendindices"); break; case SVGA3D_DECLUSAGE_NORMAL: - _debug_printf("_normal" ); + _debug_printf("_normal"); break; case SVGA3D_DECLUSAGE_PSIZE: - _debug_printf("_psize" ); + _debug_printf("_psize"); break; case SVGA3D_DECLUSAGE_TEXCOORD: _debug_printf("_texcoord"); break; case SVGA3D_DECLUSAGE_TANGENT: - _debug_printf("_tangent" ); + _debug_printf("_tangent"); break; case SVGA3D_DECLUSAGE_BINORMAL: - _debug_printf("_binormal" ); + _debug_printf("_binormal"); break; case SVGA3D_DECLUSAGE_TESSFACTOR: - _debug_printf("_tessfactor" ); + _debug_printf("_tessfactor"); break; case SVGA3D_DECLUSAGE_POSITIONT: - _debug_printf("_positiont" ); + _debug_printf("_positiont"); break; case SVGA3D_DECLUSAGE_COLOR: - _debug_printf("_color" ); + _debug_printf("_color"); break; case SVGA3D_DECLUSAGE_FOG: - _debug_printf("_fog" ); + _debug_printf("_fog"); break; case SVGA3D_DECLUSAGE_DEPTH: - _debug_printf("_depth" ); + _debug_printf("_depth"); break; case SVGA3D_DECLUSAGE_SAMPLE: _debug_printf("_sample"); break; default: - assert( 0 ); - return; + assert(!"Unknown usage"); + _debug_printf("_???"); } - if (semantic.usage_index != 0) { - _debug_printf("%d", semantic.usage_index ); + if (usage_index) { + _debug_printf("%u", usage_index); } } -static void dump_dstreg( struct sh_dstreg dstreg, const struct dump_info *di ) +static void +dump_dstreg(struct sh_dstreg dstreg, + struct sh_srcreg *indreg, + const struct dump_info *di) { union { struct sh_reg reg; struct sh_dstreg dstreg; - } u; + } u = { { 0 } }; assert( (dstreg.modifier & (SVGA3DDSTMOD_SATURATE | SVGA3DDSTMOD_PARTIALPRECISION)) == dstreg.modifier ); @@ -346,7 +395,7 @@ static void dump_dstreg( struct sh_dstreg dstreg, const struct dump_info *di ) _debug_printf( " " ); u.dstreg = dstreg; - dump_reg( u.reg, NULL, di ); + dump_reg( u.reg, indreg, di); if (dstreg.write_mask != SVGA3DWRITEMASK_ALL) { _debug_printf( "." ); if (dstreg.write_mask & SVGA3DWRITEMASK_0) @@ -362,23 +411,13 @@ static void dump_dstreg( struct sh_dstreg dstreg, const struct dump_info *di ) static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, const struct dump_info *di ) { - union { - struct sh_reg reg; - struct sh_srcreg srcreg; - } u; - switch (srcreg.modifier) { case SVGA3DSRCMOD_NEG: case SVGA3DSRCMOD_BIASNEG: case SVGA3DSRCMOD_SIGNNEG: case SVGA3DSRCMOD_X2NEG: - _debug_printf( "-" ); - break; - case SVGA3DSRCMOD_ABS: - _debug_printf( "|" ); - break; case SVGA3DSRCMOD_ABSNEG: - _debug_printf( "-|" ); + _debug_printf( "-" ); break; case SVGA3DSRCMOD_COMP: _debug_printf( "1-" ); @@ -386,19 +425,13 @@ static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, cons case SVGA3DSRCMOD_NOT: _debug_printf( "!" ); } - - u.srcreg = srcreg; - dump_reg( u.reg, indreg, di ); + dump_reg( *(struct sh_reg *) &srcreg, indreg, di ); switch (srcreg.modifier) { case SVGA3DSRCMOD_NONE: case SVGA3DSRCMOD_NEG: case SVGA3DSRCMOD_COMP: case SVGA3DSRCMOD_NOT: break; - case SVGA3DSRCMOD_ABS: - case SVGA3DSRCMOD_ABSNEG: - _debug_printf( "|" ); - break; case SVGA3DSRCMOD_BIAS: case SVGA3DSRCMOD_BIASNEG: _debug_printf( "_bias" ); @@ -417,6 +450,10 @@ static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, cons case SVGA3DSRCMOD_DW: _debug_printf( "_dw" ); break; + case SVGA3DSRCMOD_ABS: + case SVGA3DSRCMOD_ABSNEG: + _debug_printf("_abs"); + break; default: assert( 0 ); } @@ -434,58 +471,132 @@ static void dump_srcreg( struct sh_srcreg srcreg, struct sh_srcreg *indreg, cons } } +static void +parse_op(struct dump_info *di, + const uint **token, + struct dump_op *op, + uint num_dst, + uint num_src) +{ + uint i; + + assert(num_dst <= 1); + assert(num_src <= DUMP_MAX_OP_SRC); + + op->op = *(struct sh_op *)*token; + *token += sizeof(struct sh_op) / sizeof(uint); + + if (num_dst >= 1) { + op->dst = *(struct sh_dstreg *)*token; + *token += sizeof(struct sh_dstreg) / sizeof(uint); + if (op->dst.relative && + (!di->is_ps && di->version >= SVGA3D_VS_30)) { + op->dstind = *(struct sh_srcreg *)*token; + *token += sizeof(struct sh_srcreg) / sizeof(uint); + } + } + + if (op->op.predicated) { + op->p0 = *(struct sh_srcreg *)*token; + *token += sizeof(struct sh_srcreg) / sizeof(uint); + } + + for (i = 0; i < num_src; ++i) { + op->src[i] = *(struct sh_srcreg *)*token; + *token += sizeof(struct sh_srcreg) / sizeof(uint); + if (op->src[i].relative && + ((!di->is_ps && di->version >= SVGA3D_VS_20) || + (di->is_ps && di->version >= SVGA3D_PS_30))) { + op->srcind[i] = *(struct sh_srcreg *)*token; + *token += sizeof(struct sh_srcreg) / sizeof(uint); + } + } +} + +static void +dump_inst(struct dump_info *di, + const unsigned **assem, + struct sh_op op, + const struct sh_opcode_info *info) +{ + struct dump_op dop; + boolean not_first_arg = FALSE; + uint i; + + assert(info->num_dst <= 1); + + di->indent -= info->pre_dedent; + dump_indent(di->indent); + di->indent += info->post_indent; + + dump_op(op, info->mnemonic); + + parse_op(di, assem, &dop, info->num_dst, info->num_src); + if (info->num_dst > 0) { + dump_dstreg(dop.dst, &dop.dstind, di); + not_first_arg = TRUE; + } + + for (i = 0; i < info->num_src; i++) { + if (not_first_arg) { + _debug_printf(", "); + } else { + _debug_printf(" "); + } + dump_srcreg(dop.src[i], &dop.srcind[i], di); + not_first_arg = TRUE; + } + + _debug_printf("\n"); +} + void svga_shader_dump( const unsigned *assem, unsigned dwords, unsigned do_binary ) { - const unsigned *start = assem; boolean finished = FALSE; struct dump_info di; - unsigned i; - - if (do_binary) { - for (i = 0; i < dwords; i++) - _debug_printf(" 0x%08x,\n", assem[i]); - - _debug_printf("\n\n"); - } - di.version.value = *assem++; - di.is_ps = (di.version.type == SVGA3D_PS_TYPE); + di.version = *assem++; + di.is_ps = (di.version & 0xFFFF0000) == 0xFFFF0000; + di.indent = 0; _debug_printf( "%s_%u_%u\n", di.is_ps ? "ps" : "vs", - di.version.major, - di.version.minor ); + (di.version >> 8) & 0xff, + di.version & 0xff ); while (!finished) { struct sh_op op = *(struct sh_op *) assem; - if (assem - start >= dwords) { - _debug_printf("... ran off end of buffer\n"); - assert(0); - return; - } - switch (op.opcode) { case SVGA3DOP_DCL: { struct sh_dcl dcl = *(struct sh_dcl *) assem; _debug_printf( "dcl" ); - if (sh_dstreg_type( dcl.reg ) == SVGA3DREG_SAMPLER) - dump_sampleinfo( dcl.u.ps.sampleinfo ); - else if (di.is_ps) { - if (di.version.major == 3 && - sh_dstreg_type( dcl.reg ) != SVGA3DREG_MISCTYPE) - dump_usageinfo( dcl.u.vs.semantic ); + switch (sh_dstreg_type(dcl.reg)) { + case SVGA3DREG_INPUT: + if ((di.is_ps && di.version >= SVGA3D_PS_30) || + (!di.is_ps && di.version >= SVGA3D_VS_30)) { + dump_semantic(dcl.u.semantic.usage, + dcl.u.semantic.usage_index); + } + break; + case SVGA3DREG_TEXCRDOUT: + if (!di.is_ps && di.version >= SVGA3D_VS_30) { + dump_semantic(dcl.u.semantic.usage, + dcl.u.semantic.usage_index); + } + break; + case SVGA3DREG_SAMPLER: + dump_sampleinfo( dcl.u.sampleinfo ); + break; } - else - dump_usageinfo( dcl.u.vs.semantic ); - dump_dstreg( dcl.reg, &di ); + dump_dstreg(dcl.reg, NULL, &di); _debug_printf( "\n" ); assem += sizeof( struct sh_dcl ) / sizeof( unsigned ); } @@ -518,54 +629,38 @@ svga_shader_dump( break; case SVGA3DOP_TEXCOORD: - assert( di.is_ps ); - dump_op( op, "texcoord" ); - if (0) { - struct sh_dstop dstop = *(struct sh_dstop *) assem; - dump_dstreg( dstop.dst, &di ); - assem += sizeof( struct sh_dstop ) / sizeof( unsigned ); - } - else { - struct sh_unaryop unaryop = *(struct sh_unaryop *) assem; - dump_dstreg( unaryop.dst, &di ); - _debug_printf( ", " ); - dump_srcreg( unaryop.src, NULL, &di ); - assem += sizeof( struct sh_unaryop ) / sizeof( unsigned ); + { + struct sh_opcode_info info = *svga_opcode_info(op.opcode); + + assert(di.is_ps); + if (di.version > SVGA3D_PS_13) { + assert(info.num_src == 0); + + info.num_src = 1; + } + + dump_inst(&di, &assem, op, &info); } - _debug_printf( "\n" ); break; case SVGA3DOP_TEX: - assert( di.is_ps ); - if (0) { - dump_op( op, "tex" ); - if (0) { - struct sh_dstop dstop = *(struct sh_dstop *) assem; - - dump_dstreg( dstop.dst, &di ); - assem += sizeof( struct sh_dstop ) / sizeof( unsigned ); - } - else { - struct sh_unaryop unaryop = *(struct sh_unaryop *) assem; + { + struct sh_opcode_info info = *svga_opcode_info(op.opcode); + + assert(di.is_ps); + if (di.version > SVGA3D_PS_13) { + assert(info.num_src == 0); - dump_dstreg( unaryop.dst, &di ); - _debug_printf( ", " ); - dump_srcreg( unaryop.src, NULL, &di ); - assem += sizeof( struct sh_unaryop ) / sizeof( unsigned ); + if (di.version > SVGA3D_PS_14) { + info.num_src = 2; + info.mnemonic = "texld"; + } else { + info.num_src = 1; + } } - } - else { - struct sh_binaryop binaryop = *(struct sh_binaryop *) assem; - dump_op( op, "texld" ); - dump_dstreg( binaryop.dst, &di ); - _debug_printf( ", " ); - dump_srcreg( binaryop.src0, NULL, &di ); - _debug_printf( ", " ); - dump_srcreg( binaryop.src1, NULL, &di ); - assem += sizeof( struct sh_binaryop ) / sizeof( unsigned ); + dump_inst(&di, &assem, op, &info); } - _debug_printf( "\n" ); break; case SVGA3DOP_DEF: @@ -581,6 +676,21 @@ svga_shader_dump( } break; + case SVGA3DOP_SINCOS: + { + struct sh_opcode_info info = *svga_opcode_info(op.opcode); + + if ((di.is_ps && di.version >= SVGA3D_PS_30) || + (!di.is_ps && di.version >= SVGA3D_VS_30)) { + assert(info.num_src == 3); + + info.num_src = 1; + } + + dump_inst(&di, &assem, op, &info); + } + break; + case SVGA3DOP_PHASE: _debug_printf( "phase\n" ); assem += sizeof( struct sh_op ) / sizeof( unsigned ); @@ -595,59 +705,15 @@ svga_shader_dump( } break; - case SVGA3DOP_RET: - _debug_printf( "ret\n" ); - assem += sizeof( struct sh_op ) / sizeof( unsigned ); - break; - case SVGA3DOP_END: - _debug_printf( "end\n" ); finished = TRUE; break; default: { - const struct sh_opcode_info *info = svga_opcode_info( op.opcode ); - uint i; - uint num_src = info->num_src + op.predicated; - boolean not_first_arg = FALSE; - - assert( info->num_dst <= 1 ); - - if (op.opcode == SVGA3DOP_SINCOS && di.version.major < 3) - num_src += 2; - - dump_comp_op( op, info->mnemonic ); - assem += sizeof( struct sh_op ) / sizeof( unsigned ); - - if (info->num_dst > 0) { - struct sh_dstreg dstreg = *(struct sh_dstreg *) assem; + const struct sh_opcode_info *info = svga_opcode_info(op.opcode); - dump_dstreg( dstreg, &di ); - assem += sizeof( struct sh_dstreg ) / sizeof( unsigned ); - not_first_arg = TRUE; - } - - for (i = 0; i < num_src; i++) { - struct sh_srcreg srcreg; - struct sh_srcreg indreg; - - srcreg = *(struct sh_srcreg *) assem; - assem += sizeof( struct sh_srcreg ) / sizeof( unsigned ); - if (srcreg.relative && !di.is_ps && di.version.major >= 2) { - indreg = *(struct sh_srcreg *) assem; - assem += sizeof( struct sh_srcreg ) / sizeof( unsigned ); - } - - if (not_first_arg) - _debug_printf( ", " ); - else - _debug_printf( " " ); - dump_srcreg( srcreg, &indreg, &di ); - not_first_arg = TRUE; - } - - _debug_printf( "\n" ); + dump_inst(&di, &assem, op, info); } } } diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_op.c b/src/gallium/drivers/svga/svgadump/svga_shader_op.c index 8343bfdaab..95612a8006 100644 --- a/src/gallium/drivers/svga/svgadump/svga_shader_op.c +++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.c @@ -41,103 +41,103 @@ static struct sh_opcode_info opcode_info[] = { - { "nop", 0, 0, SVGA3DOP_NOP }, - { "mov", 1, 1, SVGA3DOP_MOV, }, - { "add", 1, 2, SVGA3DOP_ADD, }, - { "sub", 1, 2, SVGA3DOP_SUB, }, - { "mad", 1, 3, SVGA3DOP_MAD, }, - { "mul", 1, 2, SVGA3DOP_MUL, }, - { "rcp", 1, 1, SVGA3DOP_RCP, }, - { "rsq", 1, 1, SVGA3DOP_RSQ, }, - { "dp3", 1, 2, SVGA3DOP_DP3, }, - { "dp4", 1, 2, SVGA3DOP_DP4, }, - { "min", 1, 2, SVGA3DOP_MIN, }, - { "max", 1, 2, SVGA3DOP_MAX, }, - { "slt", 1, 2, SVGA3DOP_SLT, }, - { "sge", 1, 2, SVGA3DOP_SGE, }, - { "exp", 1, 1, SVGA3DOP_EXP, }, - { "log", 1, 1, SVGA3DOP_LOG, }, - { "lit", 1, 1, SVGA3DOP_LIT, }, - { "dst", 1, 2, SVGA3DOP_DST, }, - { "lrp", 1, 3, SVGA3DOP_LRP, }, - { "frc", 1, 1, SVGA3DOP_FRC, }, - { "m4x4", 1, 2, SVGA3DOP_M4x4, }, - { "m4x3", 1, 2, SVGA3DOP_M4x3, }, - { "m3x4", 1, 2, SVGA3DOP_M3x4, }, - { "m3x3", 1, 2, SVGA3DOP_M3x3, }, - { "m3x2", 1, 2, SVGA3DOP_M3x2, }, - { "call", 0, 1, SVGA3DOP_CALL, }, - { "callnz", 0, 2, SVGA3DOP_CALLNZ, }, - { "loop", 0, 2, SVGA3DOP_LOOP, }, - { "ret", 0, 0, SVGA3DOP_RET, }, - { "endloop", 0, 0, SVGA3DOP_ENDLOOP, }, - { "label", 0, 1, SVGA3DOP_LABEL, }, - { "dcl", 0, 0, SVGA3DOP_DCL, }, - { "pow", 1, 2, SVGA3DOP_POW, }, - { "crs", 1, 2, SVGA3DOP_CRS, }, - { "sgn", 1, 3, SVGA3DOP_SGN, }, - { "abs", 1, 1, SVGA3DOP_ABS, }, - { "nrm", 1, 1, SVGA3DOP_NRM, }, /* 3-componenet normalization */ - { "sincos", 1, 1, SVGA3DOP_SINCOS, }, - { "rep", 0, 1, SVGA3DOP_REP, }, - { "endrep", 0, 0, SVGA3DOP_ENDREP, }, - { "if", 0, 1, SVGA3DOP_IF, }, - { "ifc", 0, 2, SVGA3DOP_IFC, }, - { "else", 0, 0, SVGA3DOP_ELSE, }, - { "endif", 0, 0, SVGA3DOP_ENDIF, }, - { "break", 0, 0, SVGA3DOP_BREAK, }, - { "breakc", 0, 0, SVGA3DOP_BREAKC, }, - { "mova", 1, 1, SVGA3DOP_MOVA, }, - { "defb", 0, 0, SVGA3DOP_DEFB, }, - { "defi", 0, 0, SVGA3DOP_DEFI, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "???", 0, 0, SVGA3DOP_INVALID, }, - { "texcoord", 0, 0, SVGA3DOP_TEXCOORD, }, - { "texkill", 1, 0, SVGA3DOP_TEXKILL, }, - { "tex", 0, 0, SVGA3DOP_TEX, }, - { "texbem", 1, 1, SVGA3DOP_TEXBEM, }, - { "texbeml", 1, 1, SVGA3DOP_TEXBEML, }, - { "texreg2ar", 1, 1, SVGA3DOP_TEXREG2AR, }, - { "texreg2gb", 1, 1, SVGA3DOP_TEXREG2GB, }, - { "texm3x2pad", 1, 1, SVGA3DOP_TEXM3x2PAD, }, - { "texm3x2tex", 1, 1, SVGA3DOP_TEXM3x2TEX, }, - { "texm3x3pad", 1, 1, SVGA3DOP_TEXM3x3PAD, }, - { "texm3x3tex", 1, 1, SVGA3DOP_TEXM3x3TEX, }, - { "reserved0", 0, 0, SVGA3DOP_RESERVED0, }, - { "texm3x3spec", 1, 2, SVGA3DOP_TEXM3x3SPEC, }, - { "texm3x3vspec", 1, 1, SVGA3DOP_TEXM3x3VSPEC,}, - { "expp", 1, 1, SVGA3DOP_EXPP, }, - { "logp", 1, 1, SVGA3DOP_LOGP, }, - { "cnd", 1, 3, SVGA3DOP_CND, }, - { "def", 0, 0, SVGA3DOP_DEF, }, - { "texreg2rgb", 1, 1, SVGA3DOP_TEXREG2RGB, }, - { "texdp3tex", 1, 1, SVGA3DOP_TEXDP3TEX, }, - { "texm3x2depth", 1, 1, SVGA3DOP_TEXM3x2DEPTH,}, - { "texdp3", 1, 1, SVGA3DOP_TEXDP3, }, - { "texm3x3", 1, 1, SVGA3DOP_TEXM3x3, }, - { "texdepth", 1, 0, SVGA3DOP_TEXDEPTH, }, - { "cmp", 1, 3, SVGA3DOP_CMP, }, - { "bem", 1, 2, SVGA3DOP_BEM, }, - { "dp2add", 1, 3, SVGA3DOP_DP2ADD, }, - { "dsx", 1, 1, SVGA3DOP_INVALID, }, - { "dsy", 1, 1, SVGA3DOP_INVALID, }, - { "texldd", 1, 1, SVGA3DOP_INVALID, }, - { "setp", 1, 2, SVGA3DOP_SETP, }, - { "texldl", 1, 1, SVGA3DOP_INVALID, }, - { "breakp", 1, 1, SVGA3DOP_INVALID, }, + { "nop", 0, 0, 0, 0, SVGA3DOP_NOP }, + { "mov", 1, 1, 0, 0, SVGA3DOP_MOV, }, + { "add", 1, 2, 0, 0, SVGA3DOP_ADD, }, + { "sub", 1, 2, 0, 0, SVGA3DOP_SUB, }, + { "mad", 1, 3, 0, 0, SVGA3DOP_MAD, }, + { "mul", 1, 2, 0, 0, SVGA3DOP_MUL, }, + { "rcp", 1, 1, 0, 0, SVGA3DOP_RCP, }, + { "rsq", 1, 1, 0, 0, SVGA3DOP_RSQ, }, + { "dp3", 1, 2, 0, 0, SVGA3DOP_DP3, }, + { "dp4", 1, 2, 0, 0, SVGA3DOP_DP4, }, + { "min", 1, 2, 0, 0, SVGA3DOP_MIN, }, + { "max", 1, 2, 0, 0, SVGA3DOP_MAX, }, + { "slt", 1, 2, 0, 0, SVGA3DOP_SLT, }, + { "sge", 1, 2, 0, 0, SVGA3DOP_SGE, }, + { "exp", 1, 1, 0, 0, SVGA3DOP_EXP, }, + { "log", 1, 1, 0, 0, SVGA3DOP_LOG, }, + { "lit", 1, 1, 0, 0, SVGA3DOP_LIT, }, + { "dst", 1, 2, 0, 0, SVGA3DOP_DST, }, + { "lrp", 1, 3, 0, 0, SVGA3DOP_LRP, }, + { "frc", 1, 1, 0, 0, SVGA3DOP_FRC, }, + { "m4x4", 1, 2, 0, 0, SVGA3DOP_M4x4, }, + { "m4x3", 1, 2, 0, 0, SVGA3DOP_M4x3, }, + { "m3x4", 1, 2, 0, 0, SVGA3DOP_M3x4, }, + { "m3x3", 1, 2, 0, 0, SVGA3DOP_M3x3, }, + { "m3x2", 1, 2, 0, 0, SVGA3DOP_M3x2, }, + { "call", 0, 1, 0, 0, SVGA3DOP_CALL, }, + { "callnz", 0, 2, 0, 0, SVGA3DOP_CALLNZ, }, + { "loop", 0, 2, 0, 1, SVGA3DOP_LOOP, }, + { "ret", 0, 0, 0, 0, SVGA3DOP_RET, }, + { "endloop", 0, 0, 1, 0, SVGA3DOP_ENDLOOP, }, + { "label", 0, 1, 0, 0, SVGA3DOP_LABEL, }, + { "dcl", 0, 0, 0, 0, SVGA3DOP_DCL, }, + { "pow", 1, 2, 0, 0, SVGA3DOP_POW, }, + { "crs", 1, 2, 0, 0, SVGA3DOP_CRS, }, + { "sgn", 1, 3, 0, 0, SVGA3DOP_SGN, }, + { "abs", 1, 1, 0, 0, SVGA3DOP_ABS, }, + { "nrm", 1, 1, 0, 0, SVGA3DOP_NRM, }, /* 3-componenet normalization */ + { "sincos", 1, 3, 0, 0, SVGA3DOP_SINCOS, }, + { "rep", 0, 1, 0, 1, SVGA3DOP_REP, }, + { "endrep", 0, 0, 1, 0, SVGA3DOP_ENDREP, }, + { "if", 0, 1, 0, 1, SVGA3DOP_IF, }, + { "ifc", 0, 2, 0, 1, SVGA3DOP_IFC, }, + { "else", 0, 0, 1, 1, SVGA3DOP_ELSE, }, + { "endif", 0, 0, 1, 0, SVGA3DOP_ENDIF, }, + { "break", 0, 0, 0, 0, SVGA3DOP_BREAK, }, + { "breakc", 0, 2, 0, 0, SVGA3DOP_BREAKC, }, + { "mova", 1, 1, 0, 0, SVGA3DOP_MOVA, }, + { "defb", 0, 0, 0, 0, SVGA3DOP_DEFB, }, + { "defi", 0, 0, 0, 0, SVGA3DOP_DEFI, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "???", 0, 0, 0, 0, SVGA3DOP_INVALID, }, + { "texcoord", 1, 0, 0, 0, SVGA3DOP_TEXCOORD, }, + { "texkill", 1, 0, 0, 0, SVGA3DOP_TEXKILL, }, + { "tex", 1, 0, 0, 0, SVGA3DOP_TEX, }, + { "texbem", 1, 1, 0, 0, SVGA3DOP_TEXBEM, }, + { "texbeml", 1, 1, 0, 0, SVGA3DOP_TEXBEML, }, + { "texreg2ar", 1, 1, 0, 0, SVGA3DOP_TEXREG2AR, }, + { "texreg2gb", 1, 1, 0, 0, SVGA3DOP_TEXREG2GB, }, + { "texm3x2pad", 1, 1, 0, 0, SVGA3DOP_TEXM3x2PAD, }, + { "texm3x2tex", 1, 1, 0, 0, SVGA3DOP_TEXM3x2TEX, }, + { "texm3x3pad", 1, 1, 0, 0, SVGA3DOP_TEXM3x3PAD, }, + { "texm3x3tex", 1, 1, 0, 0, SVGA3DOP_TEXM3x3TEX, }, + { "reserved0", 0, 0, 0, 0, SVGA3DOP_RESERVED0, }, + { "texm3x3spec", 1, 2, 0, 0, SVGA3DOP_TEXM3x3SPEC, }, + { "texm3x3vspec", 1, 1, 0, 0, SVGA3DOP_TEXM3x3VSPEC,}, + { "expp", 1, 1, 0, 0, SVGA3DOP_EXPP, }, + { "logp", 1, 1, 0, 0, SVGA3DOP_LOGP, }, + { "cnd", 1, 3, 0, 0, SVGA3DOP_CND, }, + { "def", 0, 0, 0, 0, SVGA3DOP_DEF, }, + { "texreg2rgb", 1, 1, 0, 0, SVGA3DOP_TEXREG2RGB, }, + { "texdp3tex", 1, 1, 0, 0, SVGA3DOP_TEXDP3TEX, }, + { "texm3x2depth", 1, 1, 0, 0, SVGA3DOP_TEXM3x2DEPTH,}, + { "texdp3", 1, 1, 0, 0, SVGA3DOP_TEXDP3, }, + { "texm3x3", 1, 1, 0, 0, SVGA3DOP_TEXM3x3, }, + { "texdepth", 1, 0, 0, 0, SVGA3DOP_TEXDEPTH, }, + { "cmp", 1, 3, 0, 0, SVGA3DOP_CMP, }, + { "bem", 1, 2, 0, 0, SVGA3DOP_BEM, }, + { "dp2add", 1, 3, 0, 0, SVGA3DOP_DP2ADD, }, + { "dsx", 1, 1, 0, 0, SVGA3DOP_INVALID, }, + { "dsy", 1, 1, 0, 0, SVGA3DOP_INVALID, }, + { "texldd", 1, 4, 0, 0, SVGA3DOP_INVALID, }, + { "setp", 1, 2, 0, 0, SVGA3DOP_SETP, }, + { "texldl", 1, 2, 0, 0, SVGA3DOP_INVALID, }, + { "breakp", 0, 1, 0, 0, SVGA3DOP_INVALID, }, }; const struct sh_opcode_info *svga_opcode_info( uint op ) diff --git a/src/gallium/drivers/svga/svgadump/svga_shader_op.h b/src/gallium/drivers/svga/svgadump/svga_shader_op.h index e558de02c5..a5ccae5ae5 100644 --- a/src/gallium/drivers/svga/svgadump/svga_shader_op.h +++ b/src/gallium/drivers/svga/svgadump/svga_shader_op.h @@ -38,6 +38,8 @@ struct sh_opcode_info const char *mnemonic; unsigned num_dst:8; unsigned num_src:8; + unsigned pre_dedent:1; + unsigned post_indent:1; unsigned svga_opcode:16; }; diff --git a/src/gallium/drivers/trace/tr_context.c b/src/gallium/drivers/trace/tr_context.c index 34ceaa41c1..df40fbade6 100644 --- a/src/gallium/drivers/trace/tr_context.c +++ b/src/gallium/drivers/trace/tr_context.c @@ -792,6 +792,24 @@ trace_context_set_blend_color(struct pipe_context *_pipe, static INLINE void +trace_context_set_stencil_ref(struct pipe_context *_pipe, + const struct pipe_stencil_ref *state) +{ + struct trace_context *tr_ctx = trace_context(_pipe); + struct pipe_context *pipe = tr_ctx->pipe; + + trace_dump_call_begin("pipe_context", "set_stencil_ref"); + + trace_dump_arg(ptr, pipe); + trace_dump_arg(stencil_ref, state); + + pipe->set_stencil_ref(pipe, state); + + trace_dump_call_end(); +} + + +static INLINE void trace_context_set_clip_state(struct pipe_context *_pipe, const struct pipe_clip_state *state) { @@ -817,24 +835,19 @@ trace_context_set_constant_buffer(struct pipe_context *_pipe, struct trace_context *tr_ctx = trace_context(_pipe); struct pipe_context *pipe = tr_ctx->pipe; - if (buffer) + if (buffer) { trace_screen_user_buffer_update(_pipe->screen, buffer); + buffer = trace_buffer_unwrap(tr_ctx, buffer); + } trace_dump_call_begin("pipe_context", "set_constant_buffer"); trace_dump_arg(ptr, pipe); trace_dump_arg(uint, shader); trace_dump_arg(uint, index); - trace_dump_arg(constant_buffer, buffer); + trace_dump_arg(ptr, buffer); - /* XXX hmm? */ - if (buffer) { - struct pipe_buffer *_buffer; - _buffer = trace_buffer_unwrap(tr_ctx, buffer); - pipe->set_constant_buffer(pipe, shader, index, _buffer); - } else { - pipe->set_constant_buffer(pipe, shader, index, buffer); - } + pipe->set_constant_buffer(pipe, shader, index, buffer); trace_dump_call_end(); } @@ -1291,6 +1304,7 @@ trace_context_create(struct trace_screen *tr_scr, tr_ctx->base.bind_vs_state = trace_context_bind_vs_state; tr_ctx->base.delete_vs_state = trace_context_delete_vs_state; tr_ctx->base.set_blend_color = trace_context_set_blend_color; + tr_ctx->base.set_stencil_ref = trace_context_set_stencil_ref; tr_ctx->base.set_clip_state = trace_context_set_clip_state; tr_ctx->base.set_constant_buffer = trace_context_set_constant_buffer; tr_ctx->base.set_framebuffer_state = trace_context_set_framebuffer_state; diff --git a/src/gallium/drivers/trace/tr_dump.c b/src/gallium/drivers/trace/tr_dump.c index 8de451c22c..1affafdddc 100644 --- a/src/gallium/drivers/trace/tr_dump.c +++ b/src/gallium/drivers/trace/tr_dump.c @@ -250,7 +250,7 @@ boolean trace_dump_trace_begin() if(!stream) { - stream = os_stream_create(filename, 0); + stream = os_file_stream_create(filename); if(!stream) return FALSE; diff --git a/src/gallium/drivers/trace/tr_dump_state.c b/src/gallium/drivers/trace/tr_dump_state.c index 6648539a0f..6da186a655 100644 --- a/src/gallium/drivers/trace/tr_dump_state.c +++ b/src/gallium/drivers/trace/tr_dump_state.c @@ -28,6 +28,7 @@ #include "pipe/p_compiler.h" #include "util/u_memory.h" +#include "util/u_format.h" #include "tgsi/tgsi_dump.h" #include "tr_dump.h" @@ -39,18 +40,7 @@ void trace_dump_format(enum pipe_format format) if (!trace_dumping_enabled_locked()) return; - trace_dump_enum(pf_name(format) ); -} - - -static void trace_dump_reference(const struct pipe_reference *reference) -{ - if (!trace_dumping_enabled_locked()) - return; - - trace_dump_struct_begin("pipe_reference"); - trace_dump_member(int, reference, count); - trace_dump_struct_end(); + trace_dump_enum(util_format_name(format) ); } @@ -227,24 +217,6 @@ void trace_dump_clip_state(const struct pipe_clip_state *state) } -void trace_dump_constant_buffer(const struct pipe_buffer *state) -{ - if (!trace_dumping_enabled_locked()) - return; - - if(!state) { - trace_dump_null(); - return; - } - - trace_dump_struct_begin("pipe_constant_buffer"); - - trace_dump_reference(&state->reference); - - trace_dump_struct_end(); -} - - void trace_dump_shader_state(const struct pipe_shader_state *state) { static char str[8192]; @@ -301,7 +273,6 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_ trace_dump_member(uint, &state->stencil[i], fail_op); trace_dump_member(uint, &state->stencil[i], zpass_op); trace_dump_member(uint, &state->stencil[i], zfail_op); - trace_dump_member(uint, &state->stencil[i], ref_value); trace_dump_member(uint, &state->stencil[i], valuemask); trace_dump_member(uint, &state->stencil[i], writemask); trace_dump_struct_end(); @@ -321,23 +292,8 @@ void trace_dump_depth_stencil_alpha_state(const struct pipe_depth_stencil_alpha_ trace_dump_struct_end(); } -static void trace_dump_rt_blend_state(const struct pipe_rt_blend_state *state) -{ - trace_dump_member(uint, state, rgb_func); - trace_dump_member(uint, state, rgb_src_factor); - trace_dump_member(uint, state, rgb_dst_factor); - - trace_dump_member(uint, state, alpha_func); - trace_dump_member(uint, state, alpha_src_factor); - trace_dump_member(uint, state, alpha_dst_factor); - - trace_dump_member(uint, state, colormask); - -} - void trace_dump_blend_state(const struct pipe_blend_state *state) { - unsigned valid_entries = 1; if (!trace_dumping_enabled_locked()) return; @@ -346,25 +302,28 @@ void trace_dump_blend_state(const struct pipe_blend_state *state) return; } - trace_dump_struct_begin("pipe_blend_state"); + trace_dump_bytes(state, sizeof *state); +} - trace_dump_member(bool, state, dither); - trace_dump_member(bool, state, logicop_enable); - trace_dump_member(uint, state, logicop_func); +void trace_dump_blend_color(const struct pipe_blend_color *state) +{ + if (!trace_dumping_enabled_locked()) + return; - trace_dump_member(bool, state, independent_blend_enable); + if(!state) { + trace_dump_null(); + return; + } - if (state->independent_blend_enable) - valid_entries = PIPE_MAX_COLOR_BUFS; + trace_dump_struct_begin("pipe_blend_color"); - trace_dump_struct_array(rt_blend_state, state->rt, valid_entries); + trace_dump_member_array(float, state, color); trace_dump_struct_end(); } - -void trace_dump_blend_color(const struct pipe_blend_color *state) +void trace_dump_stencil_ref(const struct pipe_stencil_ref *state) { if (!trace_dumping_enabled_locked()) return; @@ -374,14 +333,13 @@ void trace_dump_blend_color(const struct pipe_blend_color *state) return; } - trace_dump_struct_begin("pipe_blend_color"); + trace_dump_struct_begin("pipe_stencil_ref"); - trace_dump_member_array(float, state, color); + trace_dump_member_array(uint, state, ref_value); trace_dump_struct_end(); } - void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state) { if (!trace_dumping_enabled_locked()) @@ -420,11 +378,11 @@ void trace_dump_sampler_state(const struct pipe_sampler_state *state) trace_dump_member(uint, state, compare_mode); trace_dump_member(uint, state, compare_func); trace_dump_member(bool, state, normalized_coords); + trace_dump_member(uint, state, max_anisotropy); trace_dump_member(float, state, lod_bias); trace_dump_member(float, state, min_lod); trace_dump_member(float, state, max_lod); trace_dump_member_array(float, state, border_color); - trace_dump_member(float, state, max_anisotropy); trace_dump_struct_end(); } @@ -442,8 +400,6 @@ void trace_dump_surface(const struct pipe_surface *state) trace_dump_struct_begin("pipe_surface"); - trace_dump_reference(&state->reference); - trace_dump_member(format, state, format); trace_dump_member(uint, state, width); trace_dump_member(uint, state, height); diff --git a/src/gallium/drivers/trace/tr_dump_state.h b/src/gallium/drivers/trace/tr_dump_state.h index c7860fd6e1..3400367d82 100644 --- a/src/gallium/drivers/trace/tr_dump_state.h +++ b/src/gallium/drivers/trace/tr_dump_state.h @@ -47,8 +47,6 @@ void trace_dump_scissor_state(const struct pipe_scissor_state *state); void trace_dump_clip_state(const struct pipe_clip_state *state); -void trace_dump_constant_buffer(const struct pipe_buffer *state); - void trace_dump_token(const struct tgsi_token *token); void trace_dump_shader_state(const struct pipe_shader_state *state); @@ -59,6 +57,8 @@ void trace_dump_blend_state(const struct pipe_blend_state *state); void trace_dump_blend_color(const struct pipe_blend_color *state); +void trace_dump_stencil_ref(const struct pipe_stencil_ref *state); + void trace_dump_framebuffer_state(const struct pipe_framebuffer_state *state); void trace_dump_sampler_state(const struct pipe_sampler_state *state); diff --git a/src/gallium/include/pipe/p_context.h b/src/gallium/include/pipe/p_context.h index f1e6a60e04..f82b77903e 100644 --- a/src/gallium/include/pipe/p_context.h +++ b/src/gallium/include/pipe/p_context.h @@ -186,8 +186,11 @@ struct pipe_context { void (*set_blend_color)( struct pipe_context *, const struct pipe_blend_color * ); + void (*set_stencil_ref)( struct pipe_context *, + const struct pipe_stencil_ref * ); + void (*set_clip_state)( struct pipe_context *, - const struct pipe_clip_state * ); + const struct pipe_clip_state * ); void (*set_constant_buffer)( struct pipe_context *, uint shader, uint index, diff --git a/src/gallium/include/pipe/p_format.h b/src/gallium/include/pipe/p_format.h index 2894e13e7d..f33b0639ef 100644 --- a/src/gallium/include/pipe/p_format.h +++ b/src/gallium/include/pipe/p_format.h @@ -165,11 +165,6 @@ enum pipe_format { PIPE_FORMAT_COUNT }; -/** - * Builds pipe format name from format token. - */ -extern const char *pf_name( enum pipe_format format ); - enum pipe_video_chroma_format { diff --git a/src/gallium/include/pipe/p_state.h b/src/gallium/include/pipe/p_state.h index 68369570b9..5ac5c87813 100644 --- a/src/gallium/include/pipe/p_state.h +++ b/src/gallium/include/pipe/p_state.h @@ -199,9 +199,8 @@ struct pipe_stencil_state unsigned fail_op:3; /**< PIPE_STENCIL_OP_x */ unsigned zpass_op:3; /**< PIPE_STENCIL_OP_x */ unsigned zfail_op:3; /**< PIPE_STENCIL_OP_x */ - ubyte ref_value; - ubyte valuemask; - ubyte writemask; + unsigned valuemask:8; + unsigned writemask:8; }; @@ -251,6 +250,10 @@ struct pipe_blend_color float color[4]; }; +struct pipe_stencil_ref +{ + ubyte ref_value[2]; +}; struct pipe_framebuffer_state { @@ -278,10 +281,10 @@ struct pipe_sampler_state unsigned compare_mode:1; /**< PIPE_TEX_COMPARE_x */ unsigned compare_func:3; /**< PIPE_FUNC_x */ unsigned normalized_coords:1; /**< Are coords normalized to [0,1]? */ + unsigned max_anisotropy:6; float lod_bias; /**< LOD/lambda bias */ float min_lod, max_lod; /**< LOD clamp range, after bias */ float border_color[4]; - float max_anisotropy; }; diff --git a/src/gallium/state_trackers/dri/dri_context.c b/src/gallium/state_trackers/dri/dri_context.c index 5033c3c85b..908cef454e 100644 --- a/src/gallium/state_trackers/dri/dri_context.c +++ b/src/gallium/state_trackers/dri/dri_context.c @@ -166,10 +166,8 @@ dri_make_current(__DRIcontext * cPriv, if (__dri1_api_hooks) { dri1_update_drawables(ctx, draw, read); } else { - if (driDrawPriv) - dri_get_buffers(driDrawPriv); - if (driDrawPriv != driReadPriv && driReadPriv) - dri_get_buffers(driReadPriv); + dri_update_buffer(ctx->pipe->screen, + ctx->pipe->priv); } } else { st_make_current(NULL, NULL, NULL); diff --git a/src/gallium/state_trackers/dri/dri_drawable.c b/src/gallium/state_trackers/dri/dri_drawable.c index ff21f2f958..4d7596a831 100644 --- a/src/gallium/state_trackers/dri/dri_drawable.c +++ b/src/gallium/state_trackers/dri/dri_drawable.c @@ -132,14 +132,22 @@ dri_get_buffers(__DRIdrawable * dPriv) boolean have_depth = FALSE; int i, count; - buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable, - &dri_drawable->w, - &dri_drawable->h, - drawable->attachments, - drawable-> - num_attachments, &count, - dri_drawable-> - loaderPrivate); + if ((dri_screen->dri2.loader + && (dri_screen->dri2.loader->base.version > 2) + && (dri_screen->dri2.loader->getBuffersWithFormat != NULL))) + buffers = (*dri_screen->dri2.loader->getBuffersWithFormat) + (dri_drawable, &dri_drawable->w, &dri_drawable->h, + drawable->attachments, drawable->num_attachments, + &count, dri_drawable->loaderPrivate); + else + buffers = (*dri_screen->dri2.loader->getBuffers) (dri_drawable, + &dri_drawable->w, + &dri_drawable->h, + drawable->attachments, + drawable-> + num_attachments, &count, + dri_drawable-> + loaderPrivate); if (buffers == NULL) { return; @@ -276,7 +284,20 @@ dri_update_buffer(struct pipe_screen *screen, void *context_private) { struct dri_context *ctx = (struct dri_context *)context_private; + if (ctx->d_stamp == *ctx->dPriv->pStamp && + ctx->r_stamp == *ctx->rPriv->pStamp) + return; + + ctx->d_stamp = *ctx->dPriv->pStamp; + ctx->r_stamp = *ctx->rPriv->pStamp; + + st_flush(ctx->st, PIPE_FLUSH_RENDER_CACHE, NULL); + + /* Ask the X server for new renderbuffers. */ dri_get_buffers(ctx->dPriv); + if (ctx->dPriv != ctx->rPriv) + dri_get_buffers(ctx->rPriv); + } void @@ -346,12 +367,12 @@ dri_create_buffer(__DRIscreen * sPriv, case 24: if (visual->stencilBits == 0) { drawable->depth_stencil_format = (screen->d_depth_bits_last) ? - PIPE_FORMAT_X8Z24_UNORM: - PIPE_FORMAT_Z24X8_UNORM; + PIPE_FORMAT_X8Z24_UNORM: + PIPE_FORMAT_Z24X8_UNORM; } else { drawable->depth_stencil_format = (screen->sd_depth_bits_last) ? - PIPE_FORMAT_S8Z24_UNORM: - PIPE_FORMAT_Z24S8_UNORM; + PIPE_FORMAT_S8Z24_UNORM: + PIPE_FORMAT_Z24S8_UNORM; } break; case 32: @@ -375,23 +396,49 @@ dri_create_buffer(__DRIscreen * sPriv, /* setup dri2 buffers information */ /* TODO incase of double buffer visual, delay fake creation */ i = 0; - drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; - if (!screen->auto_fake_front) - drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; - if (visual->doubleBufferMode) - drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; - if (visual->depthBits && visual->stencilBits) - drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; - else if (visual->depthBits) - drawable->attachments[i++] = __DRI_BUFFER_DEPTH; - else if (visual->stencilBits) - drawable->attachments[i++] = __DRI_BUFFER_STENCIL; - drawable->num_attachments = i; + if (sPriv->dri2.loader + && (sPriv->dri2.loader->base.version > 2) + && (sPriv->dri2.loader->getBuffersWithFormat != NULL)) { + drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + drawable->attachments[i++] = visual->rgbBits; + if (!screen->auto_fake_front) { + drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; + drawable->attachments[i++] = visual->rgbBits; + } + if (visual->doubleBufferMode) { + drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; + drawable->attachments[i++] = visual->rgbBits; + } + if (visual->depthBits && visual->stencilBits) { + drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + drawable->attachments[i++] = visual->depthBits + visual->stencilBits; + } else if (visual->depthBits) { + drawable->attachments[i++] = __DRI_BUFFER_DEPTH; + drawable->attachments[i++] = visual->depthBits; + } else if (visual->stencilBits) { + drawable->attachments[i++] = __DRI_BUFFER_STENCIL; + drawable->attachments[i++] = visual->stencilBits; + } + drawable->num_attachments = i / 2; + } else { + drawable->attachments[i++] = __DRI_BUFFER_FRONT_LEFT; + if (!screen->auto_fake_front) + drawable->attachments[i++] = __DRI_BUFFER_FAKE_FRONT_LEFT; + if (visual->doubleBufferMode) + drawable->attachments[i++] = __DRI_BUFFER_BACK_LEFT; + if (visual->depthBits && visual->stencilBits) + drawable->attachments[i++] = __DRI_BUFFER_DEPTH_STENCIL; + else if (visual->depthBits) + drawable->attachments[i++] = __DRI_BUFFER_DEPTH; + else if (visual->stencilBits) + drawable->attachments[i++] = __DRI_BUFFER_STENCIL; + drawable->num_attachments = i; + } drawable->desired_fences = 2; return GL_TRUE; - fail: +fail: FREE(drawable); return GL_FALSE; } diff --git a/src/gallium/state_trackers/dri/dri_screen.c b/src/gallium/state_trackers/dri/dri_screen.c index 4064976b23..77d640227f 100644 --- a/src/gallium/state_trackers/dri/dri_screen.c +++ b/src/gallium/state_trackers/dri/dri_screen.c @@ -61,6 +61,17 @@ static const __DRItexBufferExtension dri2TexBufferExtension = { dri2_set_tex_buffer2, }; +static void +dri2_flush_drawable(__DRIdrawable *draw) +{ +} + +static const __DRI2flushExtension dri2FlushExtension = { + { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, + dri2_flush_drawable, + dri2InvalidateDrawable, +}; + static const __DRIextension *dri_screen_extensions[] = { &driReadDrawableExtension, &driCopySubBufferExtension.base, @@ -68,6 +79,7 @@ static const __DRItexBufferExtension dri2TexBufferExtension = { &driFrameTrackingExtension.base, &driMediaStreamCounterExtension.base, &dri2TexBufferExtension.base, + &dri2FlushExtension.base, NULL }; @@ -97,12 +109,6 @@ dri_fill_in_modes(struct dri_screen *screen, stencil_bits_array[0] = 0; depth_buffer_factor = 1; - pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); pf_x8z24 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_X8Z24_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); @@ -115,9 +121,6 @@ dri_fill_in_modes(struct dri_screen *screen, pf_z24s8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z24S8_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); - pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM, - PIPE_TEXTURE_2D, - PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); pf_a8r8g8b8 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_A8R8G8B8_UNORM, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); @@ -125,6 +128,26 @@ dri_fill_in_modes(struct dri_screen *screen, PIPE_TEXTURE_2D, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); + /* we support buffers with different depths only if we can tell the driver + * the actual depth of each of them. */ + if (screen->sPriv->dri2.loader + && (screen->sPriv->dri2.loader->base.version > 2) + && (screen->sPriv->dri2.loader->getBuffersWithFormat != NULL)) { + pf_z16 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z16_UNORM, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); + pf_z32 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_Z32_UNORM, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_DEPTH_STENCIL, 0); + pf_r5g6b5 = p_screen->is_format_supported(p_screen, PIPE_FORMAT_R5G6B5_UNORM, + PIPE_TEXTURE_2D, + PIPE_TEXTURE_USAGE_RENDER_TARGET, 0); + } else { + pf_z16 = FALSE; + pf_z32 = FALSE; + pf_r5g6b5 = FALSE; + } + if (pf_z16) { depth_bits_array[depth_buffer_factor] = 16; stencil_bits_array[depth_buffer_factor++] = 0; diff --git a/src/gallium/state_trackers/glx/xlib/glx_usefont.c b/src/gallium/state_trackers/glx/xlib/glx_usefont.c index 16e5ce642f..e502198b20 100644 --- a/src/gallium/state_trackers/glx/xlib/glx_usefont.c +++ b/src/gallium/state_trackers/glx/xlib/glx_usefont.c @@ -33,7 +33,6 @@ #include "main/context.h" #include "main/imports.h" #include <GL/glx.h> -#include "pipe/p_compiler.h" /* Some debugging info. */ diff --git a/src/gallium/state_trackers/python/README b/src/gallium/state_trackers/python/README index e03d546830..4a06073024 100644 --- a/src/gallium/state_trackers/python/README +++ b/src/gallium/state_trackers/python/README @@ -30,7 +30,7 @@ or (in Windows) and then try running - python src/gallium/state_trackers/python/samples/tri.py + python progs/gallium/python/samples/tri.py which should show a triangle. diff --git a/src/gallium/state_trackers/python/gallium.i b/src/gallium/state_trackers/python/gallium.i index 99e177b0be..ffb084e358 100644 --- a/src/gallium/state_trackers/python/gallium.i +++ b/src/gallium/state_trackers/python/gallium.i @@ -41,13 +41,15 @@ #include "pipe/p_screen.h" #include "pipe/p_context.h" #include "pipe/p_shader_tokens.h" -#include "cso_cache/cso_context.h" +#include "os/os_stream.h" #include "util/u_inlines.h" #include "util/u_draw_quad.h" #include "util/u_tile.h" #include "util/u_math.h" #include "util/u_format.h" +#include "util/u_dump.h" #include "util/u_memory.h" +#include "cso_cache/cso_context.h" #include "tgsi/tgsi_text.h" #include "tgsi/tgsi_dump.h" @@ -93,7 +95,7 @@ %include "p_compiler.i" %include "p_defines.h"; -%include "p_format.i" +%include "p_format.h" %include "p_device.i" %include "p_context.i" diff --git a/src/gallium/state_trackers/python/p_context.i b/src/gallium/state_trackers/python/p_context.i index ce893dad45..3f36ccb621 100644 --- a/src/gallium/state_trackers/python/p_context.i +++ b/src/gallium/state_trackers/python/p_context.i @@ -130,11 +130,15 @@ struct st_context { /* * Parameter-like state (or properties) */ - + void set_blend_color(const struct pipe_blend_color *state ) { cso_set_blend_color($self->cso, state); } + void set_stencil_ref(const struct pipe_stencil_ref *state ) { + cso_set_stencil_ref($self->cso, state); + } + void set_clip(const struct pipe_clip_state *state ) { $self->pipe->set_clip_state($self->pipe, state); } diff --git a/src/gallium/state_trackers/python/p_format.i b/src/gallium/state_trackers/python/p_format.i deleted file mode 100644 index 68df009331..0000000000 --- a/src/gallium/state_trackers/python/p_format.i +++ /dev/null @@ -1,154 +0,0 @@ -/************************************************************************** - * - * Copyright 2008 Tungsten Graphics, Inc., Cedar Park, Texas. - * Copyright (c) 2008 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, 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 TUNGSTEN GRAPHICS AND/OR ITS 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. - * - **************************************************************************/ - -/* - * XXX: SWIG can't parse p_format.h, so we need to duplicate the relevant - * declarations here - */ - -%{ -#include "pipe/p_format.h" -%} - -enum pipe_format { - PIPE_FORMAT_NONE, - PIPE_FORMAT_A8R8G8B8_UNORM, - PIPE_FORMAT_X8R8G8B8_UNORM, - PIPE_FORMAT_B8G8R8A8_UNORM, - PIPE_FORMAT_B8G8R8X8_UNORM, - PIPE_FORMAT_A1R5G5B5_UNORM, - PIPE_FORMAT_A4R4G4B4_UNORM, - PIPE_FORMAT_R5G6B5_UNORM, - PIPE_FORMAT_A2B10G10R10_UNORM, - PIPE_FORMAT_L8_UNORM, - PIPE_FORMAT_A8_UNORM, - PIPE_FORMAT_I8_UNORM, - PIPE_FORMAT_A8L8_UNORM, - PIPE_FORMAT_L16_UNORM, - PIPE_FORMAT_YCBCR, - PIPE_FORMAT_YCBCR_REV, - PIPE_FORMAT_Z16_UNORM, - PIPE_FORMAT_Z32_UNORM, - PIPE_FORMAT_Z32_FLOAT, - PIPE_FORMAT_S8Z24_UNORM, - PIPE_FORMAT_Z24S8_UNORM, - PIPE_FORMAT_X8Z24_UNORM, - PIPE_FORMAT_Z24X8_UNORM, - PIPE_FORMAT_S8_UNORM, - PIPE_FORMAT_R64_FLOAT, - PIPE_FORMAT_R64G64_FLOAT, - PIPE_FORMAT_R64G64B64_FLOAT, - PIPE_FORMAT_R64G64B64A64_FLOAT, - PIPE_FORMAT_R32_FLOAT, - PIPE_FORMAT_R32G32_FLOAT, - PIPE_FORMAT_R32G32B32_FLOAT, - PIPE_FORMAT_R32G32B32A32_FLOAT, - PIPE_FORMAT_R32_UNORM, - PIPE_FORMAT_R32G32_UNORM, - PIPE_FORMAT_R32G32B32_UNORM, - PIPE_FORMAT_R32G32B32A32_UNORM, - PIPE_FORMAT_R32_USCALED, - PIPE_FORMAT_R32G32_USCALED, - PIPE_FORMAT_R32G32B32_USCALED, - PIPE_FORMAT_R32G32B32A32_USCALED, - PIPE_FORMAT_R32_SNORM, - PIPE_FORMAT_R32G32_SNORM, - PIPE_FORMAT_R32G32B32_SNORM, - PIPE_FORMAT_R32G32B32A32_SNORM, - PIPE_FORMAT_R32_SSCALED, - PIPE_FORMAT_R32G32_SSCALED, - PIPE_FORMAT_R32G32B32_SSCALED, - PIPE_FORMAT_R32G32B32A32_SSCALED, - PIPE_FORMAT_R16_UNORM, - PIPE_FORMAT_R16G16_UNORM, - PIPE_FORMAT_R16G16B16_UNORM, - PIPE_FORMAT_R16G16B16A16_UNORM, - PIPE_FORMAT_R16_USCALED, - PIPE_FORMAT_R16G16_USCALED, - PIPE_FORMAT_R16G16B16_USCALED, - PIPE_FORMAT_R16G16B16A16_USCALED, - PIPE_FORMAT_R16_SNORM, - PIPE_FORMAT_R16G16_SNORM, - PIPE_FORMAT_R16G16B16_SNORM, - PIPE_FORMAT_R16G16B16A16_SNORM, - PIPE_FORMAT_R16_SSCALED, - PIPE_FORMAT_R16G16_SSCALED, - PIPE_FORMAT_R16G16B16_SSCALED, - PIPE_FORMAT_R16G16B16A16_SSCALED, - PIPE_FORMAT_R8_UNORM, - PIPE_FORMAT_R8G8_UNORM, - PIPE_FORMAT_R8G8B8_UNORM, - PIPE_FORMAT_R8G8B8A8_UNORM, - PIPE_FORMAT_R8G8B8X8_UNORM, - PIPE_FORMAT_R8_USCALED, - PIPE_FORMAT_R8G8_USCALED, - PIPE_FORMAT_R8G8B8_USCALED, - PIPE_FORMAT_R8G8B8A8_USCALED, - PIPE_FORMAT_R8G8B8X8_USCALED, - PIPE_FORMAT_R8_SNORM, - PIPE_FORMAT_R8G8_SNORM, - PIPE_FORMAT_R8G8B8_SNORM, - PIPE_FORMAT_R8G8B8A8_SNORM, - PIPE_FORMAT_R8G8B8X8_SNORM, - PIPE_FORMAT_B6G5R5_SNORM, - PIPE_FORMAT_A8B8G8R8_SNORM, - PIPE_FORMAT_X8B8G8R8_SNORM, - PIPE_FORMAT_R8_SSCALED, - PIPE_FORMAT_R8G8_SSCALED, - PIPE_FORMAT_R8G8B8_SSCALED, - PIPE_FORMAT_R8G8B8A8_SSCALED, - PIPE_FORMAT_R8G8B8X8_SSCALED, - PIPE_FORMAT_R32_FIXED, - PIPE_FORMAT_R32G32_FIXED, - PIPE_FORMAT_R32G32B32_FIXED, - PIPE_FORMAT_R32G32B32A32_FIXED, - - PIPE_FORMAT_L8_SRGB, - PIPE_FORMAT_A8L8_SRGB, - PIPE_FORMAT_R8G8B8_SRGB, - PIPE_FORMAT_R8G8B8A8_SRGB, - PIPE_FORMAT_R8G8B8X8_SRGB, - PIPE_FORMAT_A8R8G8B8_SRGB, - PIPE_FORMAT_X8R8G8B8_SRGB, - PIPE_FORMAT_B8G8R8A8_SRGB, - PIPE_FORMAT_B8G8R8X8_SRGB, - - PIPE_FORMAT_X8UB8UG8SR8S_NORM, - PIPE_FORMAT_B6UG5SR5S_NORM, - - PIPE_FORMAT_DXT1_RGB, - PIPE_FORMAT_DXT1_RGBA, - PIPE_FORMAT_DXT3_RGBA, - PIPE_FORMAT_DXT5_RGBA, - - PIPE_FORMAT_DXT1_SRGB, - PIPE_FORMAT_DXT1_SRGBA, - PIPE_FORMAT_DXT3_SRGBA, - PIPE_FORMAT_DXT5_SRGBA, -}; - diff --git a/src/gallium/state_trackers/python/p_state.i b/src/gallium/state_trackers/python/p_state.i index 90f157e0ab..5afe4d4908 100644 --- a/src/gallium/state_trackers/python/p_state.i +++ b/src/gallium/state_trackers/python/p_state.i @@ -44,6 +44,53 @@ %array_class(struct pipe_stencil_state, StencilArray); +%extend pipe_rt_blend_state +{ + struct pipe_rt_blend_state * + __getitem__(int index) + { + if(index < 0 || index >= PIPE_MAX_COLOR_BUFS) + SWIG_exception(SWIG_ValueError, "index out of bounds"); + return $self + index; + fail: + return NULL; + }; +}; + + +%extend pipe_blend_state +{ + pipe_blend_state(void) + { + return CALLOC_STRUCT(pipe_blend_state); + } + + %cstring_input_binary(const char *STRING, unsigned LENGTH); + pipe_blend_state(const char *STRING, unsigned LENGTH) + { + struct pipe_blend_state *state; + state = CALLOC_STRUCT(pipe_framebuffer_state); + if (state) { + LENGTH = MIN2(sizeof *state, LENGTH); + memcpy(state, STRING, LENGTH); + } + return state; + } + + %cstring_output_allocate_size(char **STRING, int *LENGTH, os_free(*$1)); + void __str__(char **STRING, int *LENGTH) + { + struct os_stream *stream; + + stream = os_str_stream_create(1); + util_dump_blend_state(stream, $self); + + *STRING = os_str_stream_get_and_close(stream); + *LENGTH = strlen(*STRING); + } +}; + + %extend pipe_framebuffer_state { pipe_framebuffer_state(void) { diff --git a/src/gallium/state_trackers/python/st_device.c b/src/gallium/state_trackers/python/st_device.c index 1146a8b0c3..a3798a5521 100644 --- a/src/gallium/state_trackers/python/st_device.c +++ b/src/gallium/state_trackers/python/st_device.c @@ -157,7 +157,7 @@ st_context_create(struct st_device *st_dev) st_device_reference(&st_ctx->st_dev, st_dev); - st_ctx->pipe = st_dev->screen->create_context(st_dev->screen, NULL); + st_ctx->pipe = st_dev->screen->context_create(st_dev->screen, NULL); if(!st_ctx->pipe) { st_context_destroy(st_ctx); return NULL; diff --git a/src/gallium/state_trackers/vega/polygon.c b/src/gallium/state_trackers/vega/polygon.c index f56ea0c8b4..c06dbf5206 100644 --- a/src/gallium/state_trackers/vega/polygon.c +++ b/src/gallium/state_trackers/vega/polygon.c @@ -307,6 +307,7 @@ static void draw_polygon(struct vg_context *ctx, void polygon_fill(struct polygon *poly, struct vg_context *ctx) { struct pipe_depth_stencil_alpha_state dsa; + struct pipe_stencil_ref sr; struct pipe_blend_state blend; VGfloat bounds[4]; VGfloat min_x, min_y, max_x, max_y; @@ -325,6 +326,9 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) set_blend_for_fill(&blend); memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); + memset(&sr, 0, sizeof(struct pipe_stencil_ref)); + /* only need a fixed 0. Rely on default or move it out at least? */ + cso_set_stencil_ref(ctx->cso_context, &sr); cso_save_blend(ctx->cso_context); cso_save_depth_stencil_alpha(ctx->cso_context); @@ -336,7 +340,6 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT; dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].ref_value = 0; dsa.stencil[0].valuemask = ~0; cso_set_blend(ctx->cso_context, &blend); @@ -352,7 +355,6 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].ref_value = 0; dsa.stencil[0].valuemask = ~0; /* back */ @@ -362,7 +364,6 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; dsa.stencil[1].func = PIPE_FUNC_ALWAYS; - dsa.stencil[1].ref_value = 0; dsa.stencil[1].valuemask = ~0; cso_set_blend(ctx->cso_context, &blend); @@ -375,7 +376,6 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) cso_save_rasterizer(ctx->cso_context); dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].ref_value = 0; dsa.stencil[0].valuemask = ~0; raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH; @@ -407,7 +407,6 @@ void polygon_fill(struct polygon *poly, struct vg_context *ctx) dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; - dsa.stencil[0].ref_value = 0; dsa.stencil[0].valuemask = dsa.stencil[0].writemask; dsa.stencil[1].enabled = 0; memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth, @@ -425,6 +424,7 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) { struct array *polys = polyarray->array; struct pipe_depth_stencil_alpha_state dsa; + struct pipe_stencil_ref sr; struct pipe_blend_state blend; VGfloat min_x = polyarray->min_x; VGfloat min_y = polyarray->min_y; @@ -442,6 +442,9 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) set_blend_for_fill(&blend); memset(&dsa, 0, sizeof(struct pipe_depth_stencil_alpha_state)); + memset(&sr, 0, sizeof(struct pipe_stencil_ref)); + /* only need a fixed 0. Rely on default or move it out at least? */ + cso_set_stencil_ref(ctx->cso_context, &sr); cso_save_blend(ctx->cso_context); cso_save_depth_stencil_alpha(ctx->cso_context); @@ -453,7 +456,6 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INVERT; dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].ref_value = 0; dsa.stencil[0].valuemask = ~0; cso_set_blend(ctx->cso_context, &blend); @@ -472,7 +474,6 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_INCR_WRAP; dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].ref_value = 0; dsa.stencil[0].valuemask = ~0; /* back */ @@ -482,7 +483,6 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) dsa.stencil[1].zfail_op = PIPE_STENCIL_OP_KEEP; dsa.stencil[1].zpass_op = PIPE_STENCIL_OP_DECR_WRAP; dsa.stencil[1].func = PIPE_FUNC_ALWAYS; - dsa.stencil[1].ref_value = 0; dsa.stencil[1].valuemask = ~0; cso_set_blend(ctx->cso_context, &blend); @@ -498,7 +498,6 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) cso_save_rasterizer(ctx->cso_context); dsa.stencil[0].func = PIPE_FUNC_ALWAYS; - dsa.stencil[0].ref_value = 0; dsa.stencil[0].valuemask = ~0; raster.cull_mode = raster.front_winding ^ PIPE_WINDING_BOTH; @@ -536,7 +535,6 @@ void polygon_array_fill(struct polygon_array *polyarray, struct vg_context *ctx) dsa.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; dsa.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; dsa.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; - dsa.stencil[0].ref_value = 0; dsa.stencil[0].valuemask = dsa.stencil[0].writemask; dsa.stencil[1].enabled = 0; memcpy(&dsa.depth, &ctx->state.g3d.dsa.depth, diff --git a/src/gallium/state_trackers/wgl/opengl32.def b/src/gallium/state_trackers/wgl/opengl32.def index 5daa6ddd41..01a29d0391 100644 --- a/src/gallium/state_trackers/wgl/opengl32.def +++ b/src/gallium/state_trackers/wgl/opengl32.def @@ -362,7 +362,7 @@ EXPORTS wglShareLists wglSwapBuffers wglSwapLayerBuffers -; wglSwapMultipleBuffers + wglSwapMultipleBuffers wglUseFontBitmapsA wglUseFontBitmapsW wglUseFontOutlinesA diff --git a/src/gallium/state_trackers/wgl/opengl32.mingw.def b/src/gallium/state_trackers/wgl/opengl32.mingw.def index 6ebb31a6f1..0bceee0697 100644 --- a/src/gallium/state_trackers/wgl/opengl32.mingw.def +++ b/src/gallium/state_trackers/wgl/opengl32.mingw.def @@ -362,7 +362,7 @@ EXPORTS wglShareLists = wglShareLists@8 wglSwapBuffers = wglSwapBuffers@4 wglSwapLayerBuffers = wglSwapLayerBuffers@8 -; wglSwapMultipleBuffers = wglSwapMultipleBuffers@8 + wglSwapMultipleBuffers = wglSwapMultipleBuffers@8 wglUseFontBitmapsA = wglUseFontBitmapsA@16 wglUseFontBitmapsW = wglUseFontBitmapsW@16 wglUseFontOutlinesA = wglUseFontOutlinesA@32 diff --git a/src/gallium/state_trackers/wgl/stw_context.c b/src/gallium/state_trackers/wgl/stw_context.c index 0785d2c6b8..05ccd5febc 100644 --- a/src/gallium/state_trackers/wgl/stw_context.c +++ b/src/gallium/state_trackers/wgl/stw_context.c @@ -75,6 +75,9 @@ DrvCopyContext( struct stw_context *dst; BOOL ret = FALSE; + if (!stw_dev) + return FALSE; + pipe_mutex_lock( stw_dev->ctx_mutex ); src = stw_lookup_context_locked( dhrcSource ); @@ -102,13 +105,15 @@ DrvShareLists( struct stw_context *ctx2; BOOL ret = FALSE; + if (!stw_dev) + return FALSE; + pipe_mutex_lock( stw_dev->ctx_mutex ); ctx1 = stw_lookup_context_locked( dhglrc1 ); ctx2 = stw_lookup_context_locked( dhglrc2 ); - if (ctx1 && ctx2 && - ctx1->iPixelFormat == ctx2->iPixelFormat) { + if (ctx1 && ctx2) { ret = _mesa_share_state(ctx2->st->ctx, ctx1->st->ctx); } diff --git a/src/gallium/state_trackers/wgl/stw_device.c b/src/gallium/state_trackers/wgl/stw_device.c index 7785aba467..e5fa6ac8eb 100644 --- a/src/gallium/state_trackers/wgl/stw_device.c +++ b/src/gallium/state_trackers/wgl/stw_device.c @@ -152,24 +152,27 @@ stw_cleanup_thread(void) void stw_cleanup(void) { - unsigned i; + DHGLRC dhglrc; debug_printf("%s\n", __FUNCTION__); if (!stw_dev) return; + /* + * Abort cleanup if there are still active contexts. In some situations + * this DLL may be unloaded before the DLL that is using GL contexts is. + */ pipe_mutex_lock( stw_dev->ctx_mutex ); - { - /* Ensure all contexts are destroyed */ - i = handle_table_get_first_handle(stw_dev->ctx_table); - while (i) { - DrvDeleteContext(i); - i = handle_table_get_next_handle(stw_dev->ctx_table, i); - } - handle_table_destroy(stw_dev->ctx_table); - } + dhglrc = handle_table_get_first_handle(stw_dev->ctx_table); pipe_mutex_unlock( stw_dev->ctx_mutex ); + if (dhglrc) { + debug_printf("%s: contexts still active -- cleanup aborted\n", __FUNCTION__); + stw_dev = NULL; + return; + } + + handle_table_destroy(stw_dev->ctx_table); stw_framebuffer_cleanup(); diff --git a/src/gallium/state_trackers/wgl/stw_framebuffer.c b/src/gallium/state_trackers/wgl/stw_framebuffer.c index 129a6298a7..02de21ccb2 100644 --- a/src/gallium/state_trackers/wgl/stw_framebuffer.c +++ b/src/gallium/state_trackers/wgl/stw_framebuffer.c @@ -179,7 +179,7 @@ stw_call_window_proc( if(!tls_data) return 0; - if (nCode < 0) + if (nCode < 0 || !stw_dev) return CallNextHookEx(tls_data->hCallWndProcHook, nCode, wParam, lParam); if (pParams->message == WM_WINDOWPOSCHANGED) { @@ -332,6 +332,9 @@ stw_framebuffer_cleanup( void ) struct stw_framebuffer *fb; struct stw_framebuffer *next; + if (!stw_dev) + return; + pipe_mutex_lock( stw_dev->fb_mutex ); fb = stw_dev->fb_head; @@ -387,6 +390,9 @@ stw_framebuffer_from_hdc( { struct stw_framebuffer *fb; + if (!stw_dev) + return NULL; + pipe_mutex_lock( stw_dev->fb_mutex ); fb = stw_framebuffer_from_hdc_locked(hdc); pipe_mutex_unlock( stw_dev->fb_mutex ); @@ -421,6 +427,9 @@ DrvSetPixelFormat( uint index; struct stw_framebuffer *fb; + if (!stw_dev) + return FALSE; + index = (uint) iPixelFormat - 1; count = stw_pixelformat_get_extended_count(); if (index >= count) @@ -475,6 +484,9 @@ DrvPresentBuffers(HDC hdc, PGLPRESENTBUFFERSDATA data) struct pipe_screen *screen; struct pipe_surface *surface; + if (!stw_dev) + return FALSE; + fb = stw_framebuffer_from_hdc( hdc ); if (fb == NULL) return FALSE; @@ -576,6 +588,9 @@ DrvSwapBuffers( struct stw_framebuffer *fb; struct pipe_surface *surface = NULL; + if (!stw_dev) + return FALSE; + fb = stw_framebuffer_from_hdc( hdc ); if (fb == NULL) return FALSE; diff --git a/src/gallium/state_trackers/wgl/stw_getprocaddress.c b/src/gallium/state_trackers/wgl/stw_getprocaddress.c index 8875dc22f3..d43a55fa9e 100644 --- a/src/gallium/state_trackers/wgl/stw_getprocaddress.c +++ b/src/gallium/state_trackers/wgl/stw_getprocaddress.c @@ -34,6 +34,8 @@ #include "glapi/glapi.h" #include "stw_ext_gallium.h" +#include "stw_device.h" +#include "stw_icd.h" struct stw_extension_entry { @@ -73,6 +75,9 @@ DrvGetProcAddress( { const struct stw_extension_entry *entry; + if (!stw_dev) + return NULL; + if (lpszProc[0] == 'w' && lpszProc[1] == 'g' && lpszProc[2] == 'l') for (entry = stw_extension_entries; entry->name; entry++) if (strcmp( lpszProc, entry->name ) == 0) diff --git a/src/gallium/state_trackers/wgl/stw_pixelformat.c b/src/gallium/state_trackers/wgl/stw_pixelformat.c index 7d4c2430b0..b750b03695 100644 --- a/src/gallium/state_trackers/wgl/stw_pixelformat.c +++ b/src/gallium/state_trackers/wgl/stw_pixelformat.c @@ -302,6 +302,9 @@ DrvDescribePixelFormat( (void) hdc; + if (!stw_dev) + return 0; + count = stw_pixelformat_get_extended_count(); index = (uint) iPixelFormat - 1; diff --git a/src/gallium/state_trackers/wgl/stw_wgl.c b/src/gallium/state_trackers/wgl/stw_wgl.c index bb199fdd25..5fbb7bf7cf 100644 --- a/src/gallium/state_trackers/wgl/stw_wgl.c +++ b/src/gallium/state_trackers/wgl/stw_wgl.c @@ -97,6 +97,19 @@ wglSwapBuffers( } +WINGDIAPI DWORD WINAPI +wglSwapMultipleBuffers(UINT n, + CONST WGLSWAP *ps) +{ + UINT i; + + for (i =0; i < n; ++i) + wglSwapBuffers(ps->hdc); + + return 0; +} + + WINGDIAPI BOOL APIENTRY wglSwapLayerBuffers( HDC hdc, diff --git a/src/gallium/state_trackers/wgl/stw_wgl.h b/src/gallium/state_trackers/wgl/stw_wgl.h index a98179944a..57baaf0a11 100644 --- a/src/gallium/state_trackers/wgl/stw_wgl.h +++ b/src/gallium/state_trackers/wgl/stw_wgl.h @@ -59,5 +59,21 @@ wglSetPixelFormat(HDC hdc, int iPixelFormat, CONST PIXELFORMATDESCRIPTOR *ppfd); +#if defined(__MINGW32__) || (WINVER < 0x0500) + +typedef struct _WGLSWAP +{ + HDC hdc; + UINT uiFlags; +} WGLSWAP; + +#define WGL_SWAPMULTIPLE_MAX 16 + +WINGDIAPI DWORD WINAPI +wglSwapMultipleBuffers(UINT n, + CONST WGLSWAP *ps); + +#endif + #endif /* STW_WGL_H_ */ diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c index 7457fe1c6d..5b67392435 100644 --- a/src/gallium/state_trackers/xorg/xorg_dri2.c +++ b/src/gallium/state_trackers/xorg/xorg_dri2.c @@ -103,14 +103,26 @@ dri2_do_create_buffer(DrawablePtr pDraw, DRI2BufferPtr buffer, unsigned int form pipe_texture_reference(&tex, exa_priv->depth_stencil_tex); else { struct pipe_texture template; + unsigned depthBits = (format != 0) ? format : pDraw->depth; memset(&template, 0, sizeof(template)); template.target = PIPE_TEXTURE_2D; - if (buffer->attachment == DRI2BufferDepth) - template.format = ms->ds_depth_bits_last ? - PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM; - else - template.format = ms->ds_depth_bits_last ? - PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM; + if (buffer->attachment == DRI2BufferDepth) { + switch(depthBits) { + case 16: + template.format = PIPE_FORMAT_Z16_UNORM; + break; + case 32: + template.format = PIPE_FORMAT_Z32_UNORM; + break; + default: + template.format = ms->ds_depth_bits_last ? + PIPE_FORMAT_X8Z24_UNORM : PIPE_FORMAT_Z24X8_UNORM; + break; + } + } else { + template.format = ms->ds_depth_bits_last ? + PIPE_FORMAT_S8Z24_UNORM : PIPE_FORMAT_Z24S8_UNORM; + } template.width0 = pDraw->width; template.height0 = pDraw->height; template.depth0 = 1; diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c index ae66c4baa9..665efdc0f0 100644 --- a/src/gallium/state_trackers/xorg/xorg_exa.c +++ b/src/gallium/state_trackers/xorg/xorg_exa.c @@ -45,6 +45,7 @@ #include "util/u_rect.h" #include "util/u_math.h" #include "util/u_debug.h" +#include "util/u_format.h" #define DEBUG_PRINT 0 #define ROUND_UP_TEXTURES 1 @@ -360,7 +361,7 @@ ExaPrepareSolid(PixmapPtr pPixmap, int alu, Pixel planeMask, Pixel fg) if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) { - XORG_FALLBACK("format %s", pf_name(priv->tex->format)); + XORG_FALLBACK("format %s", util_format_name(priv->tex->format)); } return xorg_solid_bind_state(exa, priv, fg); @@ -441,12 +442,12 @@ ExaPrepareCopy(PixmapPtr pSrcPixmap, PixmapPtr pDstPixmap, int xdir, if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) - XORG_FALLBACK("pDst format %s", pf_name(priv->tex->format)); + XORG_FALLBACK("pDst format %s", util_format_name(priv->tex->format)); if (!exa->scrn->is_format_supported(exa->scrn, src_priv->tex->format, src_priv->tex->target, PIPE_TEXTURE_USAGE_SAMPLER, 0)) - XORG_FALLBACK("pSrc format %s", pf_name(src_priv->tex->format)); + XORG_FALLBACK("pSrc format %s", util_format_name(src_priv->tex->format)); exa->copy.src = src_priv; exa->copy.dst = priv; @@ -652,7 +653,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, PIPE_TEXTURE_USAGE_RENDER_TARGET, 0)) - XORG_FALLBACK("pDst format: %s", pf_name(priv->tex->format)); + XORG_FALLBACK("pDst format: %s", util_format_name(priv->tex->format)); if (priv->picture_format != pDstPicture->format) XORG_FALLBACK("pDst pic_format: %s != %s", @@ -667,7 +668,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, PIPE_TEXTURE_USAGE_SAMPLER, 0)) - XORG_FALLBACK("pSrc format: %s", pf_name(priv->tex->format)); + XORG_FALLBACK("pSrc format: %s", util_format_name(priv->tex->format)); if (!picture_check_formats(priv, pSrcPicture)) XORG_FALLBACK("pSrc pic_format: %s != %s", @@ -684,7 +685,7 @@ ExaPrepareComposite(int op, PicturePtr pSrcPicture, if (!exa->scrn->is_format_supported(exa->scrn, priv->tex->format, priv->tex->target, PIPE_TEXTURE_USAGE_SAMPLER, 0)) - XORG_FALLBACK("pMask format: %s", pf_name(priv->tex->format)); + XORG_FALLBACK("pMask format: %s", util_format_name(priv->tex->format)); if (!picture_check_formats(priv, pMaskPicture)) XORG_FALLBACK("pMask pic_format: %s != %s", diff --git a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c index 3b1c3860a4..5cbf0dd2c5 100644 --- a/src/gallium/winsys/drm/radeon/core/radeon_buffer.c +++ b/src/gallium/winsys/drm/radeon/core/radeon_buffer.c @@ -217,9 +217,10 @@ static void radeon_buffer_set_tiling(struct radeon_winsys *ws, boolean microtiled, boolean macrotiled) { + struct radeon_winsys_priv *priv = ((struct radeon_winsys *)ws)->priv; struct radeon_pipe_buffer *radeon_buffer = (struct radeon_pipe_buffer*)buffer; - uint32_t flags = 0; + uint32_t flags = 0, old_flags, old_pitch; if (microtiled) { flags |= RADEON_BO_FLAGS_MICRO_TILE; @@ -228,7 +229,17 @@ static void radeon_buffer_set_tiling(struct radeon_winsys *ws, flags |= RADEON_BO_FLAGS_MACRO_TILE; } - radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch); + radeon_bo_get_tiling(radeon_buffer->bo, &old_flags, &old_pitch); + + if (flags != old_flags || pitch != old_pitch) { + /* Tiling determines how DRM treats the buffer data. + * We must flush CS when changing it if the buffer is referenced. */ + if (radeon_bo_is_referenced_by_cs(radeon_buffer->bo, priv->cs)) { + priv->flush_cb(priv->flush_data); + } + + radeon_bo_set_tiling(radeon_buffer->bo, flags, pitch); + } } static void radeon_fence_reference(struct pipe_winsys *ws, diff --git a/src/gallium/winsys/drm/radeon/python/README b/src/gallium/winsys/drm/radeon/python/README index d9e49bce67..339836a592 100644 --- a/src/gallium/winsys/drm/radeon/python/README +++ b/src/gallium/winsys/drm/radeon/python/README @@ -12,4 +12,4 @@ Run as: export PYTHONPATH=$PWD/build/linux-x86-debug/gallium/winsys/drm/radeon/python:$PWD/build/linux-x86-debug/gallium/state_trackers/python - python src/gallium/state_trackers/python/samples/tri.py + python progs/gallium/python/samples/tri.py diff --git a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c index 03dbd76c37..e9e5990cf5 100644 --- a/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_llvmpipe_winsys.c @@ -251,13 +251,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: - if (!stw_init(&stw_winsys)) { - return FALSE; - } - return stw_init_thread(); + stw_init(&stw_winsys); + stw_init_thread(); + break; case DLL_THREAD_ATTACH: - return stw_init_thread(); + stw_init_thread(); + break; case DLL_THREAD_DETACH: stw_cleanup_thread(); diff --git a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c index 2078020f8f..71360e55aa 100644 --- a/src/gallium/winsys/gdi/gdi_softpipe_winsys.c +++ b/src/gallium/winsys/gdi/gdi_softpipe_winsys.c @@ -297,13 +297,13 @@ DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpReserved) { switch (fdwReason) { case DLL_PROCESS_ATTACH: - if (!stw_init(&stw_winsys)) { - return FALSE; - } - return stw_init_thread(); + stw_init(&stw_winsys); + stw_init_thread(); + break; case DLL_THREAD_ATTACH: - return stw_init_thread(); + stw_init_thread(); + break; case DLL_THREAD_DETACH: stw_cleanup_thread(); diff --git a/src/glsl/apps/process.c b/src/glsl/apps/process.c index 2d2ab911ac..e65f35cc00 100644 --- a/src/glsl/apps/process.c +++ b/src/glsl/apps/process.c @@ -47,6 +47,7 @@ main(int argc, unsigned int i; if (argc != 3) { + printf("Usage: process infile outfile\n"); return 1; } diff --git a/src/glsl/apps/purify.c b/src/glsl/apps/purify.c index 8c01f4fc6a..3019e8b220 100644 --- a/src/glsl/apps/purify.c +++ b/src/glsl/apps/purify.c @@ -45,6 +45,7 @@ main(int argc, FILE *out; if (argc != 3) { + printf("Usage: purify infile outfile\n"); return 1; } diff --git a/src/glsl/apps/tokenise.c b/src/glsl/apps/tokenise.c index 9ff73157e9..c70c3ccbb1 100644 --- a/src/glsl/apps/tokenise.c +++ b/src/glsl/apps/tokenise.c @@ -46,6 +46,7 @@ main(int argc, unsigned int i; if (argc != 3) { + printf("Usage: tokenize infile outfile\n"); return 1; } diff --git a/src/glsl/apps/version.c b/src/glsl/apps/version.c index 40a4a069c3..0420f97294 100644 --- a/src/glsl/apps/version.c +++ b/src/glsl/apps/version.c @@ -45,6 +45,7 @@ main(int argc, FILE *out; if (argc != 3) { + printf("Usage: version infile outfile\n"); return 1; } diff --git a/src/glsl/cl/sl_cl_parse.c b/src/glsl/cl/sl_cl_parse.c index e256ab8213..8106ff6f61 100644 --- a/src/glsl/cl/sl_cl_parse.c +++ b/src/glsl/cl/sl_cl_parse.c @@ -120,6 +120,11 @@ #define TYPE_CENTER 95 #define TYPE_CENTROID 96 +/* layout qualifiers */ +#define LAYOUT_QUALIFIER_NONE 0 +#define LAYOUT_QUALIFIER_UPPER_LEFT 1 +#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER 2 + /* type specifier */ #define TYPE_SPECIFIER_VOID 0 #define TYPE_SPECIFIER_BOOL 1 @@ -297,6 +302,10 @@ struct parse_dict { int out; int inout; + int layout; + int origin_upper_left; + int pixel_center_integer; + int _struct; int __constructor; @@ -316,6 +325,9 @@ struct parse_dict { int _false; int _true; + + int all; + int _GL_ARB_fragment_coord_conventions; }; @@ -334,6 +346,8 @@ struct parse_context { unsigned int shader_type; unsigned int parsing_builtin; + unsigned int fragment_coord_conventions:1; + char error[256]; int process_error; }; @@ -451,6 +465,10 @@ _fetch_token(struct parse_context *ctx, case SL_PP_IDENTIFIER: case SL_PP_UINT: case SL_PP_FLOAT: + case SL_PP_EXTENSION_REQUIRE: + case SL_PP_EXTENSION_ENABLE: + case SL_PP_EXTENSION_WARN: + case SL_PP_EXTENSION_DISABLE: case SL_PP_EOF: ctx->tokens_read++; break; @@ -462,6 +480,10 @@ _fetch_token(struct parse_context *ctx, } +/** + * Try to parse/match a particular token. + * \return 0 for success, -1 for error. + */ static int _parse_token(struct parse_context *ctx, enum sl_pp_token token, @@ -477,6 +499,10 @@ _parse_token(struct parse_context *ctx, } +/** + * Try to parse an identifer. + * \return 0 for success, -1 for error + */ static int _parse_id(struct parse_context *ctx, int id, @@ -707,8 +733,65 @@ _parse_centroid_qualifier(struct parse_context *ctx, static int -_parse_type_qualifier(struct parse_context *ctx, - struct parse_state *ps) +_parse_layout_qualifier(struct parse_context *ctx, + struct parse_state *ps) +{ + if (_parse_id(ctx, ctx->dict.layout, ps) == 0) { + if (!ctx->fragment_coord_conventions) { + _error(ctx, "GL_ARB_fragment_coord_conventions extension must be enabled " + "in order to use a layout qualifier"); + return -1; + } + + /* Layout qualifiers are only defined for fragment shaders, + * so do an early check. + */ + if (ctx->shader_type != 1) { + _error(ctx, "layout qualifiers are only valid for fragment shaders"); + return -1; + } + + /* start of a parenthesised list of layout qualifiers */ + + if (_parse_token(ctx, SL_PP_LPAREN, ps)) { + _error(ctx, "expected `('"); + return -1; + } + + /* parse comma-separated ID list */ + while (1) { + if (_parse_id(ctx, ctx->dict.origin_upper_left, ps) == 0) { + _emit(ctx, &ps->out, LAYOUT_QUALIFIER_UPPER_LEFT); + } + else if (_parse_id(ctx, ctx->dict.pixel_center_integer, ps) == 0) { + _emit(ctx, &ps->out, LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER); + } + else { + _error(ctx, "expected a layout qualifier name"); + return -1; + } + + if (_parse_token(ctx, SL_PP_RPAREN, ps) == 0) { + /* all done */ + break; + } + else if (_parse_token(ctx, SL_PP_COMMA, ps) == 0) { + /* another layout qualifier is coming */ + } + else { + _error(ctx, "expected `,' or `)'"); + return -1; + } + } + } + + return 0; +} + + +static int +_parse_storage_qualifier(struct parse_context *ctx, + struct parse_state *ps) { struct parse_state p = *ps; const struct sl_pp_token_info *input = _fetch_token(ctx, p.in); @@ -1006,13 +1089,19 @@ _parse_fully_specified_type(struct parse_context *ctx, { struct parse_state p = *ps; + if (_parse_layout_qualifier(ctx, &p)) { + return -1; + } + _emit(ctx, &p.out, LAYOUT_QUALIFIER_NONE); + if (_parse_invariant_qualifier(ctx, &p)) { _emit(ctx, &p.out, TYPE_VARIANT); } + if (_parse_centroid_qualifier(ctx, &p)) { _emit(ctx, &p.out, TYPE_CENTER); } - if (_parse_type_qualifier(ctx, &p)) { + if (_parse_storage_qualifier(ctx, &p)) { _emit(ctx, &p.out, TYPE_QUALIFIER_NONE); } if (_parse_precision(ctx, &p)) { @@ -1698,7 +1787,7 @@ _parse_parameter_declaration(struct parse_context *ctx, (void) e; - if (_parse_type_qualifier(ctx, &p)) { + if (_parse_storage_qualifier(ctx, &p)) { _emit(ctx, &p.out, TYPE_QUALIFIER_NONE); } _parse_parameter_qualifier(ctx, &p); @@ -2679,14 +2768,59 @@ _parse_external_declaration(struct parse_context *ctx, static int +_parse_extensions(struct parse_context *ctx, + struct parse_state *ps) +{ + for (;;) { + const struct sl_pp_token_info *input = _fetch_token(ctx, ps->in); + unsigned int enable; + + if (!input) { + return -1; + } + + switch (input->token) { + case SL_PP_EXTENSION_REQUIRE: + case SL_PP_EXTENSION_ENABLE: + case SL_PP_EXTENSION_WARN: + enable = 1; + break; + case SL_PP_EXTENSION_DISABLE: + enable = 0; + break; + default: + return 0; + } + + ps->in++; + if (input->data.extension == ctx->dict.all) { + ctx->fragment_coord_conventions = enable; + } + else if (input->data.extension == ctx->dict._GL_ARB_fragment_coord_conventions) { + ctx->fragment_coord_conventions = enable; + } + } +} + + +static int _parse_translation_unit(struct parse_context *ctx, struct parse_state *ps) { _emit(ctx, &ps->out, REVISION); + if (_parse_extensions(ctx, ps)) { + return -1; + } if (_parse_external_declaration(ctx, ps)) { return -1; } - while (_parse_external_declaration(ctx, ps) == 0) { + for (;;) { + if (_parse_extensions(ctx, ps)) { + return -1; + } + if (_parse_external_declaration(ctx, ps)) { + break; + } } _emit(ctx, &ps->out, EXTERNAL_NULL); if (_parse_token(ctx, SL_PP_EOF, ps)) { @@ -2772,6 +2906,10 @@ sl_cl_compile(struct sl_pp_context *context, ADD_NAME(ctx, out); ADD_NAME(ctx, inout); + ADD_NAME(ctx, layout); + ADD_NAME(ctx, origin_upper_left); + ADD_NAME(ctx, pixel_center_integer); + ADD_NAME_STR(ctx, _struct, "struct"); ADD_NAME(ctx, __constructor); @@ -2792,12 +2930,17 @@ sl_cl_compile(struct sl_pp_context *context, ADD_NAME_STR(ctx, _false, "false"); ADD_NAME_STR(ctx, _true, "true"); + ADD_NAME(ctx, all); + ADD_NAME_STR(ctx, _GL_ARB_fragment_coord_conventions, "GL_ARB_fragment_coord_conventions"); + ctx.out_buf = NULL; ctx.out_cap = 0; ctx.shader_type = shader_type; ctx.parsing_builtin = 1; + ctx.fragment_coord_conventions = 0; + ctx.error[0] = '\0'; ctx.process_error = 0; diff --git a/src/glsl/pp/sl_pp_context.h b/src/glsl/pp/sl_pp_context.h index 983a09c02a..8abb9708b8 100644 --- a/src/glsl/pp/sl_pp_context.h +++ b/src/glsl/pp/sl_pp_context.h @@ -45,7 +45,6 @@ struct sl_pp_extension { int name; /*< GL_VENDOR_extension_name */ - int enabled; }; struct sl_pp_predefined { @@ -53,6 +52,15 @@ struct sl_pp_predefined { int value; }; +union sl_pp_if_state { + struct { + unsigned int condition:1; + unsigned int went_thru_else:1; + unsigned int had_true_cond:1; + } u; + unsigned int value; +}; + struct sl_pp_context { char *cstr_pool; unsigned int cstr_pool_max; @@ -68,7 +76,7 @@ struct sl_pp_context { struct sl_pp_predefined predefined[SL_PP_MAX_PREDEFINED]; unsigned int num_predefined; - unsigned int if_stack[SL_PP_MAX_IF_NESTING]; + union sl_pp_if_state if_stack[SL_PP_MAX_IF_NESTING]; unsigned int if_ptr; unsigned int if_value; diff --git a/src/glsl/pp/sl_pp_extension.c b/src/glsl/pp/sl_pp_extension.c index 777e42d0fc..d119677c26 100644 --- a/src/glsl/pp/sl_pp_extension.c +++ b/src/glsl/pp/sl_pp_extension.c @@ -53,8 +53,6 @@ sl_pp_context_add_extension(struct sl_pp_context *context, return -1; } - ext.enabled = 0; - context->extensions[context->num_extensions++] = ext; assert(context->num_extensions <= sizeof(context->extensions)); @@ -62,6 +60,7 @@ sl_pp_context_add_extension(struct sl_pp_context *context, return 0; } + /** * Process a "#extension name: behavior" directive. */ @@ -75,7 +74,6 @@ sl_pp_process_extension(struct sl_pp_context *context, int extension_name = -1; int behavior = -1; struct sl_pp_token_info out; - struct sl_pp_extension *extension = NULL; /* Grab the extension name. */ if (first < last && input[first].token == SL_PP_IDENTIFIER) { @@ -97,7 +95,6 @@ sl_pp_process_extension(struct sl_pp_context *context, for (i = 0; i < context->num_extensions; i++) { if (extension_name == context->extensions[i].name) { out.data.extension = extension_name; - extension = &context->extensions[i]; break; } } @@ -137,7 +134,6 @@ sl_pp_process_extension(struct sl_pp_context *context, return -1; } out.token = SL_PP_EXTENSION_REQUIRE; - extension->enabled = 1; } else if (behavior == context->dict.enable) { if (out.data.extension == -1) { /* Warning: the extension cannot be enabled. */ @@ -148,21 +144,18 @@ sl_pp_process_extension(struct sl_pp_context *context, return -1; } out.token = SL_PP_EXTENSION_ENABLE; - extension->enabled = 1; } else if (behavior == context->dict.warn) { if (out.data.extension == -1) { /* Warning: the extension is not supported. */ return 0; } out.token = SL_PP_EXTENSION_WARN; - extension->enabled = 0; } else if (behavior == context->dict.disable) { if (out.data.extension == -1) { /* Warning: the extension is not supported. */ return 0; } out.token = SL_PP_EXTENSION_DISABLE; - extension->enabled = 0; } else { strcpy(context->error_msg, "unrecognised behavior name"); return -1; diff --git a/src/glsl/pp/sl_pp_if.c b/src/glsl/pp/sl_pp_if.c index 272c3a23cc..25cb7a3ca1 100644 --- a/src/glsl/pp/sl_pp_if.c +++ b/src/glsl/pp/sl_pp_if.c @@ -40,7 +40,7 @@ _macro_is_defined(struct sl_pp_context *context, for (i = 0; i < context->num_extensions; i++) { if (macro_name == context->extensions[i].name) { - return context->extensions[i].enabled; + return 1; } } @@ -108,7 +108,7 @@ _evaluate_if_stack(struct sl_pp_context *context) unsigned int i; for (i = context->if_ptr; i < SL_PP_MAX_IF_NESTING; i++) { - if (!(context->if_stack[i] & 1)) { + if (!context->if_stack[i].u.condition) { return 0; } } @@ -182,7 +182,8 @@ _parse_if(struct sl_pp_context *context, free(state.out); context->if_ptr--; - context->if_stack[context->if_ptr] = result ? 1 : 0; + context->if_stack[context->if_ptr].value = 0; + context->if_stack[context->if_ptr].u.condition = result ? 1 : 0; context->if_value = _evaluate_if_stack(context); return 0; @@ -191,19 +192,24 @@ _parse_if(struct sl_pp_context *context, static int _parse_else(struct sl_pp_context *context) { + union sl_pp_if_state *state = &context->if_stack[context->if_ptr]; + if (context->if_ptr == SL_PP_MAX_IF_NESTING) { strcpy(context->error_msg, "no matching `#if'"); return -1; } - /* Bit b1 indicates we already went through #else. */ - if (context->if_stack[context->if_ptr] & 2) { + if (state->u.went_thru_else) { strcpy(context->error_msg, "no matching `#if'"); return -1; } - /* Invert current condition value and mark that we are in the #else block. */ - context->if_stack[context->if_ptr] = (1 - (context->if_stack[context->if_ptr] & 1)) | 2; + /* Once we had a true condition, the subsequent #elifs should always be false. */ + state->u.had_true_cond |= state->u.condition; + + /* Update current condition value and mark that we are in the #else block. */ + state->u.condition = !(state->u.had_true_cond | state->u.condition); + state->u.went_thru_else = 1; context->if_value = _evaluate_if_stack(context); return 0; @@ -233,7 +239,8 @@ sl_pp_process_ifdef(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_IDENTIFIER: context->if_ptr--; - context->if_stack[context->if_ptr] = _macro_is_defined(context, input[i].data.identifier); + context->if_stack[context->if_ptr].value = 0; + context->if_stack[context->if_ptr].u.condition = _macro_is_defined(context, input[i].data.identifier); context->if_value = _evaluate_if_stack(context); return 0; @@ -267,7 +274,8 @@ sl_pp_process_ifndef(struct sl_pp_context *context, switch (input[i].token) { case SL_PP_IDENTIFIER: context->if_ptr--; - context->if_stack[context->if_ptr] = !_macro_is_defined(context, input[i].data.identifier); + context->if_stack[context->if_ptr].value = 0; + context->if_stack[context->if_ptr].u.condition = !_macro_is_defined(context, input[i].data.identifier); context->if_value = _evaluate_if_stack(context); return 0; @@ -292,7 +300,7 @@ sl_pp_process_elif(struct sl_pp_context *context, return -1; } - if (context->if_stack[context->if_ptr] & 1) { + if (context->if_stack[context->if_ptr].u.condition) { context->if_ptr++; if (_parse_if(context, buffer)) { return -1; @@ -300,7 +308,7 @@ sl_pp_process_elif(struct sl_pp_context *context, } /* We are still in the #if block. */ - context->if_stack[context->if_ptr] = context->if_stack[context->if_ptr] & ~2; + context->if_stack[context->if_ptr].u.went_thru_else = 0; return 0; } diff --git a/src/glsl/pp/sl_pp_process.c b/src/glsl/pp/sl_pp_process.c index f89986dd8e..315ad9bf1c 100644 --- a/src/glsl/pp/sl_pp_process.c +++ b/src/glsl/pp/sl_pp_process.c @@ -87,6 +87,7 @@ sl_pp_process_get(struct sl_pp_context *context, int found_eof = 0; if (context->process_state.out_len) { + assert(context->process_state.out); *output = context->process_state.out[0]; if (context->process_state.out_len > 1) { diff --git a/src/glu/mesa/mipmap.c b/src/glu/mesa/mipmap.c index d85ce9b9b0..ad6b6e63a6 100644 --- a/src/glu/mesa/mipmap.c +++ b/src/glu/mesa/mipmap.c @@ -287,7 +287,11 @@ gluScaleImage(GLenum format, } break; default: - return GLU_INVALID_ENUM; + { + free(tempin); + free(tempout); + return GLU_INVALID_ENUM; + } } @@ -670,6 +674,7 @@ gluBuild1DMipmaps(GLenum target, GLint components, break; default: /* Not implemented */ + free(texture); return GLU_ERROR; } } diff --git a/src/glu/mini/mipmap.c b/src/glu/mini/mipmap.c index a655d214e3..1cf739a13e 100644 --- a/src/glu/mini/mipmap.c +++ b/src/glu/mini/mipmap.c @@ -287,7 +287,11 @@ gluScaleImage(GLenum format, } break; default: - return GLU_INVALID_ENUM; + { + free(tempin); + free(tempout); + return GLU_INVALID_ENUM; + } } diff --git a/src/glu/sgi/libnurbs/internals/arc.h b/src/glu/sgi/libnurbs/internals/arc.h index e986019c3a..ca397f3b1f 100644 --- a/src/glu/sgi/libnurbs/internals/arc.h +++ b/src/glu/sgi/libnurbs/internals/arc.h @@ -108,6 +108,9 @@ public: inline Arc::Arc( Arc *j, PwlArc *p ) { + prev = NULL; + next = NULL; + link = NULL; bezierArc = NULL; pwlArc = p; type = j->type; @@ -123,6 +126,9 @@ Arc::Arc( Arc *j, PwlArc *p ) inline Arc::Arc( arc_side side, long _nuid ) { + prev = NULL; + next = NULL; + link = NULL; bezierArc = NULL; pwlArc = NULL; type = 0; diff --git a/src/glu/sgi/libnurbs/internals/bin.cc b/src/glu/sgi/libnurbs/internals/bin.cc index 54b406147b..ff75b86bed 100644 --- a/src/glu/sgi/libnurbs/internals/bin.cc +++ b/src/glu/sgi/libnurbs/internals/bin.cc @@ -49,6 +49,7 @@ Bin::Bin() { head = NULL; + current = NULL; } Bin::~Bin() diff --git a/src/glu/sgi/libnurbs/internals/bufpool.cc b/src/glu/sgi/libnurbs/internals/bufpool.cc index 8cc847ab22..53ac1a5695 100644 --- a/src/glu/sgi/libnurbs/internals/bufpool.cc +++ b/src/glu/sgi/libnurbs/internals/bufpool.cc @@ -60,6 +60,9 @@ Pool::Pool( int _buffersize, int initpoolsize, const char *n ) curblock = 0; freelist = 0; nextfree = 0; + for (int i = 0; i < NBLOCKS; i++) { + blocklist[i] = 0; + } } /*----------------------------------------------------------------------------- diff --git a/src/glu/sgi/libnurbs/internals/curve.cc b/src/glu/sgi/libnurbs/internals/curve.cc index 33e2752643..b7c4d4a9c7 100644 --- a/src/glu/sgi/libnurbs/internals/curve.cc +++ b/src/glu/sgi/libnurbs/internals/curve.cc @@ -60,6 +60,12 @@ Curve::Curve( Quilt_ptr geo, REAL pta, REAL ptb, Curve *c ) cullval = mapdesc->isCulling() ? CULL_ACCEPT : CULL_TRIVIAL_ACCEPT; order = geo->qspec[0].order; stride = MAXCOORDS; + for( int i = 0; i < MAXORDER * MAXCOORDS; i++ ) { + cpts[i] = 0; + spts[i] = 0; + } + stepsize = 0; + minstepsize = 0; REAL *ps = geo->cpts; Quiltspec_ptr qs = geo->qspec; diff --git a/src/glu/sgi/libnurbs/internals/curvelist.cc b/src/glu/sgi/libnurbs/internals/curvelist.cc index abfebb767f..8f2ee4678d 100644 --- a/src/glu/sgi/libnurbs/internals/curvelist.cc +++ b/src/glu/sgi/libnurbs/internals/curvelist.cc @@ -53,20 +53,23 @@ Curvelist::Curvelist( Quilt *quilts, REAL pta, REAL ptb ) range[0] = pta; range[1] = ptb; range[2] = ptb - pta; + needsSubdivision = 0; + stepsize = 0; } Curvelist::Curvelist( Curvelist &upper, REAL value ) { - Curvelist &lower = *this; curve = 0; for( Curve *c = upper.curve; c; c = c->next ) curve = new Curve( *c, value, curve ); - lower.range[0] = upper.range[0]; - lower.range[1] = value; - lower.range[2] = value - upper.range[0]; + range[0] = upper.range[0]; + range[1] = value; + range[2] = value - upper.range[0]; upper.range[0] = value; upper.range[2] = upper.range[1] - value; + needsSubdivision = 0; + stepsize = 0; } Curvelist::~Curvelist() diff --git a/src/glu/sgi/libnurbs/nurbtess/monoChain.cc b/src/glu/sgi/libnurbs/nurbtess/monoChain.cc index b17b9405c1..cb28129adf 100644 --- a/src/glu/sgi/libnurbs/nurbtess/monoChain.cc +++ b/src/glu/sgi/libnurbs/nurbtess/monoChain.cc @@ -264,6 +264,7 @@ monoChain* directedLineLoopToMonoChainLoop(directedLine* loop) prevCusp = temp; } } + assert(ret); ret->insert(new monoChain(prevCusp, firstCusp)); return ret; diff --git a/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc b/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc index 26d05342f9..dfdbd4e844 100644 --- a/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc +++ b/src/glu/sgi/libnurbs/nurbtess/primitiveStream.cc @@ -156,6 +156,8 @@ primStream::primStream(Int sizeLengths, Int sizeVertices) index_vertices = 0; size_lengths = sizeLengths; size_vertices = sizeVertices; + + counter = 0; } primStream::~primStream() diff --git a/src/glut/glx/glut_cmap.c b/src/glut/glx/glut_cmap.c index e8d9e1f01b..e6cb742cfe 100644 --- a/src/glut/glx/glut_cmap.c +++ b/src/glut/glx/glut_cmap.c @@ -348,7 +348,7 @@ __glutEstablishColormapsProperty(GLUTwindow * window) Window *winlist; Colormap *cmaplist; Status status; - int maxcmaps, num; + int maxcmaps, num, i; assert(!window->parent); maxcmaps = MaxCmapsOfScreen(ScreenOfDisplay(__glutDisplay, @@ -357,6 +357,9 @@ __glutEstablishColormapsProperty(GLUTwindow * window) and cmaplist, but we could. */ winlist = (Window *) malloc(maxcmaps * sizeof(Window)); cmaplist = (Colormap *) malloc(maxcmaps * sizeof(Colormap)); + for (i = 0; i < maxcmaps; i++) { + cmaplist[i] = 0; + } num = findColormaps(window, winlist, cmaplist, 0, maxcmaps); if (num < 2) { /* Property no longer needed; remove it. */ diff --git a/src/glut/glx/glut_overlay.c b/src/glut/glx/glut_overlay.c index db1abe005d..32434650eb 100644 --- a/src/glut/glx/glut_overlay.c +++ b/src/glut/glx/glut_overlay.c @@ -388,6 +388,7 @@ glutEstablishOverlay(void) if (!overlay->vis) { __glutFatalError("lacks overlay support."); } + overlay->ctx = NULL; #if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig) if (fbc) { window->ctx = __glut_glXCreateContextWithConfigSGIX(__glutDisplay, fbc, diff --git a/src/glx/dri2.c b/src/glx/dri2.c index 91053d3fb6..5de55cdbf2 100644 --- a/src/glx/dri2.c +++ b/src/glx/dri2.c @@ -81,15 +81,13 @@ static XEXT_GENERATE_FIND_DISPLAY (DRI2FindDisplay, dri2Info, dri2ExtensionName, &dri2ExtensionHooks, - 1, NULL) + 0, NULL) static Bool DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) { XExtDisplayInfo *info = DRI2FindDisplay(dpy); XExtDisplayInfo *glx_info = __glXFindDisplay(dpy); - static int glx_event_base; - static Bool found_glx_info = False; XextCheckExtension(dpy, info, dri2ExtensionName, False); @@ -126,7 +124,15 @@ DRI2WireToEvent(Display *dpy, XEvent *event, xEvent *wire) return True; } #endif +#ifdef DRI2_InvalidateBuffers + case DRI2_InvalidateBuffers: + { + xDRI2InvalidateBuffers *awire = (xDRI2InvalidateBuffers *)wire; + dri2InvalidateBuffers(dpy, awire->drawable); + return False; + } +#endif default: /* client doesn't support server event */ break; @@ -174,6 +180,7 @@ DRI2QueryVersion(Display * dpy, int *major, int *minor) XExtDisplayInfo *info = DRI2FindDisplay(dpy); xDRI2QueryVersionReply rep; xDRI2QueryVersionReq *req; + int i, nevents; XextCheckExtension(dpy, info, dri2ExtensionName, False); @@ -193,6 +200,24 @@ DRI2QueryVersion(Display * dpy, int *major, int *minor) UnlockDisplay(dpy); SyncHandle(); + switch (rep.minorVersion) { + case 1: + nevents = 0; + break; + case 2: + nevents = 1; + break; + case 3: + default: + nevents = 2; + break; + } + + for (i = 0; i < nevents; i++) { + XESetWireToEvent (dpy, info->codes->first_event + i, DRI2WireToEvent); + XESetEventToWire (dpy, info->codes->first_event + i, DRI2EventToWire); + } + return True; } diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c index 15a3ea5907..29d589cdb9 100644 --- a/src/glx/dri2_glx.c +++ b/src/glx/dri2_glx.c @@ -67,6 +67,7 @@ struct __GLXDRIdisplayPrivateRec int driMinor; int driPatch; int swapAvailable; + int invalidateAvailable; }; struct __GLXDRIcontextPrivateRec @@ -310,12 +311,18 @@ dri2WaitGL(__GLXDRIdrawable * pdraw) XFixesDestroyRegion(pdraw->psc->dpy, region); } - static void -dri2FlushFrontBuffer(__DRIdrawable * driDrawable, void *loaderPrivate) +dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *loaderPrivate) { - (void) driDrawable; - dri2WaitGL((__GLXDRIdrawable *) loaderPrivate); + __GLXDRIdrawablePrivate *pdraw = loaderPrivate; + __GLXdisplayPrivate *priv = __glXInitialize(pdraw->base.psc->dpy); + __GLXDRIdisplayPrivate *pdp = (__GLXDRIdisplayPrivate *)priv->dri2Display; + + /* Old servers don't send invalidate events */ + if (!pdp->invalidateAvailable) + dri2InvalidateBuffers(priv->dpy, pdraw->base.xDrawable); + + dri2WaitGL(loaderPrivate); } @@ -375,6 +382,10 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, (*pdraw->psc->f->flush)(pdraw->driDrawable); #endif + /* Old servers don't send invalidate events */ + if (!pdp->invalidateAvailable) + dri2InvalidateBuffers(dpyPriv->dpy, pdraw->xDrawable); + /* Old servers can't handle swapbuffers */ if (!pdp->swapAvailable) { dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height); @@ -386,11 +397,6 @@ dri2SwapBuffers(__GLXDRIdrawable *pdraw, int64_t target_msc, int64_t divisor, remainder, &ret); #endif -#if __DRI2_FLUSH_VERSION >= 2 - if (pdraw->psc->f) - (*pdraw->psc->f->flushInvalidate)(pdraw->driDrawable); -#endif - return ret; } @@ -485,6 +491,17 @@ static const __DRIextension *loader_extensions_old[] = { NULL }; +_X_HIDDEN void +dri2InvalidateBuffers(Display *dpy, XID drawable) +{ + __GLXDRIdrawable *pdraw = GetGLXDRIDrawable(dpy, drawable, NULL); + +#if __DRI2_FLUSH_VERSION >= 3 + if (pdraw && pdraw->psc->f) + pdraw->psc->f->invalidate(pdraw->driDrawable); +#endif +} + static __GLXDRIscreen * dri2CreateScreen(__GLXscreenConfigs * psc, int screen, __GLXdisplayPrivate * priv) @@ -651,11 +668,8 @@ dri2CreateDisplay(Display * dpy) } pdp->driPatch = 0; - pdp->swapAvailable = 0; -#ifdef X_DRI2SwapBuffers - if (pdp->driMinor >= 2) - pdp->swapAvailable = 1; -#endif + pdp->swapAvailable = (pdp->driMinor >= 2); + pdp->invalidateAvailable = (pdp->driMinor >= 3); pdp->base.destroyDisplay = dri2DestroyDisplay; pdp->base.createScreen = dri2CreateScreen; diff --git a/src/glx/dri_glx.c b/src/glx/dri_glx.c index 0ff53c324f..f9fe9a25db 100644 --- a/src/glx/dri_glx.c +++ b/src/glx/dri_glx.c @@ -323,6 +323,7 @@ CallCreateNewScreen(Display * dpy, int scrn, __GLXscreenConfigs * psc, framebuffer.base = MAP_FAILED; framebuffer.dev_priv = NULL; + framebuffer.size = 0; if (!XF86DRIOpenConnection(dpy, scrn, &hSAREA, &BusID)) { ErrorMessageF("XF86DRIOpenConnection failed\n"); diff --git a/src/glx/glx_pbuffer.c b/src/glx/glx_pbuffer.c index a0a02238b0..4c122ba6dd 100644 --- a/src/glx/glx_pbuffer.c +++ b/src/glx/glx_pbuffer.c @@ -186,10 +186,6 @@ DestroyPbuffer(Display * dpy, GLXDrawable drawable) #ifdef GLX_DIRECT_RENDERING -extern __GLXDRIdrawable *GetGLXDRIDrawable(Display * dpy, - GLXDrawable drawable, - int *const scrn_num); - static GLenum determineTextureTarget(const int *attribs, int numAttribs) { diff --git a/src/glx/glxclient.h b/src/glx/glxclient.h index e0b286b688..04ce781c43 100644 --- a/src/glx/glxclient.h +++ b/src/glx/glxclient.h @@ -182,6 +182,8 @@ struct __GLXDRIdrawableRec extern __GLXDRIdisplay *driswCreateDisplay(Display * dpy); extern __GLXDRIdisplay *driCreateDisplay(Display * dpy); extern __GLXDRIdisplay *dri2CreateDisplay(Display * dpy); +extern void dri2InvalidateBuffers(Display *dpy, XID drawable); + extern void DRI_glXUseXFont(Font font, int first, int count, int listbase); @@ -798,6 +800,10 @@ __driGetMscRateOML(__DRIdrawable * draw, /* So that dri2.c:DRI2WireToEvent() can access * glx_info->codes->first_event */ XExtDisplayInfo *__glXFindDisplay (Display *dpy); + +extern __GLXDRIdrawable * +GetGLXDRIDrawable(Display *dpy, GLXDrawable drawable, int *const scrn_num); + #endif #endif /* !__GLX_client_h__ */ diff --git a/src/glx/glxcmds.c b/src/glx/glxcmds.c index 706d63b36b..704e9a0b9d 100644 --- a/src/glx/glxcmds.c +++ b/src/glx/glxcmds.c @@ -110,10 +110,6 @@ GarbageCollectDRIDrawables(Display * dpy, __GLXscreenConfigs * sc) XSetErrorHandler(oldXErrorHandler); } -extern __GLXDRIdrawable *GetGLXDRIDrawable(Display * dpy, - GLXDrawable drawable, - int *const scrn_num); - /** * Get the __DRIdrawable for the drawable associated with a GLXContext * diff --git a/src/mesa/SConscript b/src/mesa/SConscript index ea5bad2825..0726fcb1a7 100644 --- a/src/mesa/SConscript +++ b/src/mesa/SConscript @@ -174,7 +174,6 @@ if env['platform'] != 'winddk': 'state_tracker/st_cb_readpixels.c', 'state_tracker/st_cb_strings.c', 'state_tracker/st_cb_texture.c', - 'state_tracker/st_cb_viewport.c', 'state_tracker/st_context.c', 'state_tracker/st_debug.c', 'state_tracker/st_draw.c', diff --git a/src/mesa/drivers/common/driverfuncs.c b/src/mesa/drivers/common/driverfuncs.c index 5c5e17820d..49d4aaedb0 100644 --- a/src/mesa/drivers/common/driverfuncs.c +++ b/src/mesa/drivers/common/driverfuncs.c @@ -26,7 +26,6 @@ #include "main/glheader.h" #include "main/imports.h" #include "main/arrayobj.h" -#include "main/buffers.h" #include "main/context.h" #include "main/framebuffer.h" #include "main/mipmap.h" @@ -50,7 +49,6 @@ #endif #include "shader/program.h" -#include "shader/prog_execute.h" #include "shader/shader_api.h" #include "tnl/tnl.h" #include "swrast/swrast.h" diff --git a/src/mesa/drivers/common/meta.c b/src/mesa/drivers/common/meta.c index e500359bb7..7116d920f7 100644 --- a/src/mesa/drivers/common/meta.c +++ b/src/mesa/drivers/common/meta.c @@ -56,7 +56,6 @@ #include "main/stencil.h" #include "main/texobj.h" #include "main/texenv.h" -#include "main/texformat.h" #include "main/teximage.h" #include "main/texparam.h" #include "main/texstate.h" diff --git a/src/mesa/drivers/dri/common/dri_metaops.c b/src/mesa/drivers/dri/common/dri_metaops.c index c7bea07dc9..dfb7d64040 100644 --- a/src/mesa/drivers/dri/common/dri_metaops.c +++ b/src/mesa/drivers/dri/common/dri_metaops.c @@ -27,17 +27,9 @@ **************************************************************************/ #include "main/arrayobj.h" -#include "main/attrib.h" -#include "main/blend.h" #include "main/bufferobj.h" -#include "main/buffers.h" -#include "main/depth.h" #include "main/enable.h" #include "main/matrix.h" -#include "main/macros.h" -#include "main/polygon.h" -#include "main/shaders.h" -#include "main/stencil.h" #include "main/texstate.h" #include "main/varray.h" #include "main/viewport.h" diff --git a/src/mesa/drivers/dri/common/dri_util.c b/src/mesa/drivers/dri/common/dri_util.c index 3649c29666..b891fca2b1 100644 --- a/src/mesa/drivers/dri/common/dri_util.c +++ b/src/mesa/drivers/dri/common/dri_util.c @@ -454,7 +454,6 @@ driCreateNewDrawable(__DRIscreen *psp, const __DRIconfig *config, pdp->driScreenPriv = psp; pdp->driContextPriv = &psp->dummyContextPriv; - pdp->validBuffers = GL_FALSE; if (!(*psp->DriverAPI.CreateBuffer)(psp, pdp, &config->modes, renderType == GLX_PIXMAP_BIT)) { @@ -485,8 +484,11 @@ dri2CreateNewDrawable(__DRIscreen *screen, if (!pdraw) return NULL; - pdraw->pClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); - pdraw->pBackClipRects = _mesa_malloc(sizeof *pdraw->pBackClipRects); + pdraw->pClipRects = &pdraw->dri2.clipRect; + pdraw->pBackClipRects = &pdraw->dri2.clipRect; + + pdraw->pStamp = &pdraw->dri2.stamp; + *pdraw->pStamp = pdraw->lastStamp + 1; return pdraw; } @@ -507,11 +509,11 @@ static void dri_put_drawable(__DRIdrawable *pdp) psp = pdp->driScreenPriv; (*psp->DriverAPI.DestroyBuffer)(pdp); - if (pdp->pClipRects) { + if (pdp->pClipRects && pdp->pClipRects != &pdp->dri2.clipRect) { _mesa_free(pdp->pClipRects); pdp->pClipRects = NULL; } - if (pdp->pBackClipRects) { + if (pdp->pBackClipRects && pdp->pClipRects != &pdp->dri2.clipRect) { _mesa_free(pdp->pBackClipRects); pdp->pBackClipRects = NULL; } @@ -581,7 +583,8 @@ driCreateNewContext(__DRIscreen *psp, const __DRIconfig *config, pcp->driScreenPriv = psp; pcp->driDrawablePriv = NULL; - + pcp->loaderPrivate = data; + /* When the first context is created for a screen, initialize a "dummy" * context. */ @@ -948,4 +951,10 @@ driCalculateSwapUsage( __DRIdrawable *dPriv, int64_t last_swap_ust, return usage; } +void +dri2InvalidateDrawable(__DRIdrawable *drawable) +{ + drawable->dri2.stamp++; +} + /*@}*/ diff --git a/src/mesa/drivers/dri/common/dri_util.h b/src/mesa/drivers/dri/common/dri_util.h index 95df702f1a..8f0cd4cf9d 100644 --- a/src/mesa/drivers/dri/common/dri_util.h +++ b/src/mesa/drivers/dri/common/dri_util.h @@ -295,7 +295,8 @@ struct __DRIdrawableRec { unsigned int index; /** - * Pointer to the "drawable has changed ID" stamp in the SAREA. + * Pointer to the "drawable has changed ID" stamp in the SAREA (or + * to dri2.stamp if DRI2 is being used). */ unsigned int *pStamp; @@ -377,7 +378,10 @@ struct __DRIdrawableRec { */ unsigned int swap_interval; - GLboolean validBuffers; + struct { + unsigned int stamp; + drm_clip_rect_t clipRect; + } dri2; }; /** @@ -413,6 +417,11 @@ struct __DRIcontextRec { * Pointer to screen on which this context was created. */ __DRIscreen *driScreenPriv; + + /** + * The loaders's private context data. This structure is opaque. + */ + void *loaderPrivate; }; /** @@ -550,4 +559,7 @@ driCalculateSwapUsage( __DRIdrawable *dPriv, extern GLint driIntersectArea( drm_clip_rect_t rect1, drm_clip_rect_t rect2 ); +extern void +dri2InvalidateDrawable(__DRIdrawable *drawable); + #endif /* _DRI_UTIL_H_ */ diff --git a/src/mesa/drivers/dri/common/drirenderbuffer.c b/src/mesa/drivers/dri/common/drirenderbuffer.c index 3126ea8476..fe38f608a9 100644 --- a/src/mesa/drivers/dri/common/drirenderbuffer.c +++ b/src/mesa/drivers/dri/common/drirenderbuffer.c @@ -1,7 +1,6 @@ #include "main/mtypes.h" #include "main/formats.h" -#include "main/framebuffer.h" #include "main/renderbuffer.h" #include "main/imports.h" #include "drirenderbuffer.h" diff --git a/src/mesa/drivers/dri/common/xmlconfig.c b/src/mesa/drivers/dri/common/xmlconfig.c index 46ba2ffbfe..477259ea7e 100644 --- a/src/mesa/drivers/dri/common/xmlconfig.c +++ b/src/mesa/drivers/dri/common/xmlconfig.c @@ -39,13 +39,6 @@ #include "dri_util.h" #include "xmlconfig.h" -/* - * OS dependent ways of getting the name of the running program - */ -#if (defined(__unix__) || defined(unix)) && !defined(USG) -#include <sys/param.h> -#endif - #undef GET_PROGRAM_NAME #if (defined(__GNU_LIBRARY__) || defined(__GLIBC__)) && !defined(__UCLIBC__) diff --git a/src/mesa/drivers/dri/i965/brw_state_cache.c b/src/mesa/drivers/dri/i965/brw_state_cache.c index 5fc47b0420..1369d97e21 100644 --- a/src/mesa/drivers/dri/i965/brw_state_cache.c +++ b/src/mesa/drivers/dri/i965/brw_state_cache.c @@ -59,15 +59,7 @@ #include "main/imports.h" #include "brw_state.h" #include "intel_batchbuffer.h" - -/* XXX: Fixme - have to include these to get the sizes of the prog_key - * structs: - */ #include "brw_wm.h" -#include "brw_vs.h" -#include "brw_clip.h" -#include "brw_sf.h" -#include "brw_gs.h" static GLuint diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c index e9315a50fe..81d5a32476 100644 --- a/src/mesa/drivers/dri/intel/intel_context.c +++ b/src/mesa/drivers/dri/intel/intel_context.c @@ -195,7 +195,6 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) __DRIscreen *screen; int i, count; unsigned int attachments[10]; - uint32_t name; const char *region_name; if (INTEL_DEBUG & DEBUG_DRI) @@ -324,11 +323,8 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) if (rb == NULL) continue; - if (rb->region) { - dri_bo_flink(rb->region->buffer, &name); - if (name == buffers[i].name) + if (rb->region && rb->region->name == buffers[i].name) continue; - } if (INTEL_DEBUG & DEBUG_DRI) fprintf(stderr, @@ -360,11 +356,8 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) if (rb != NULL) { struct intel_region *stencil_region = NULL; - if (rb->region) { - dri_bo_flink(rb->region->buffer, &name); - if (name == buffers[i].name) + if (rb->region && rb->region->name == buffers[i].name) continue; - } intel_region_reference(&stencil_region, region); intel_renderbuffer_set_region(rb, stencil_region); @@ -373,8 +366,8 @@ intel_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable) } } - drawable->validBuffers = GL_TRUE; driUpdateFramebufferSize(&intel->ctx, drawable); + drawable->lastStamp = drawable->dri2.stamp; } void diff --git a/src/mesa/drivers/dri/intel/intel_regions.c b/src/mesa/drivers/dri/intel/intel_regions.c index e2859e44f9..881653ff01 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.c +++ b/src/mesa/drivers/dri/intel/intel_regions.c @@ -42,6 +42,7 @@ #include <sys/ioctl.h> #include <errno.h> +#include <main/hash.h> #include "intel_context.h" #include "intel_regions.h" #include "intel_blit.h" @@ -228,10 +229,24 @@ intel_region_alloc_for_handle(struct intel_context *intel, GLuint width, GLuint height, GLuint pitch, GLuint handle, const char *name) { - struct intel_region *region; + struct intel_region *region, *dummy; dri_bo *buffer; int ret; + region = _mesa_HashLookup(intel->intelScreen->named_regions, handle); + if (region != NULL) { + dummy = NULL; + if (region->width != width || region->height != height || + region->cpp != cpp || region->pitch != pitch) { + fprintf(stderr, + "Region for name %d already exists but is not compatible\n", + handle); + return NULL; + } + intel_region_reference(&dummy, region); + return dummy; + } + buffer = intel_bo_gem_create_from_name(intel->bufmgr, name, handle); region = intel_region_alloc_internal(intel, cpp, @@ -248,6 +263,10 @@ intel_region_alloc_for_handle(struct intel_context *intel, return NULL; } + region->name = handle; + region->screen = intel->intelScreen; + _mesa_HashInsert(intel->intelScreen->named_regions, handle, region); + return region; } @@ -287,6 +306,9 @@ intel_region_release(struct intel_region **region_handle) region->pbo = NULL; dri_bo_unreference(region->buffer); + if (region->name > 0) + _mesa_HashRemove(region->screen->named_regions, region->name); + free(region); } *region_handle = NULL; diff --git a/src/mesa/drivers/dri/intel/intel_regions.h b/src/mesa/drivers/dri/intel/intel_regions.h index 860ae11bd2..6d36f3d88a 100644 --- a/src/mesa/drivers/dri/intel/intel_regions.h +++ b/src/mesa/drivers/dri/intel/intel_regions.h @@ -67,6 +67,9 @@ struct intel_region uint32_t tiling; /**< Which tiling mode the region is in */ uint32_t bit_6_swizzle; /**< GEM flag for address swizzling requirement */ struct intel_buffer_object *pbo; /* zero-copy uploads */ + + uint32_t name; /**< Global name for the bo */ + struct intel_screen *screen; }; diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c index 6dc20d0fef..8eed8ee737 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.c +++ b/src/mesa/drivers/dri/intel/intel_screen.c @@ -29,6 +29,7 @@ #include "main/context.h" #include "main/framebuffer.h" #include "main/renderbuffer.h" +#include "main/hash.h" #include "utils.h" #include "xmlpool.h" @@ -122,22 +123,19 @@ intelDRI2Flush(__DRIdrawable *drawable) } static void -intelDRI2FlushInvalidate(__DRIdrawable *drawable) +intelDRI2Invalidate(__DRIdrawable *drawable) { struct intel_context *intel = drawable->driContextPriv->driverPrivate; intel->using_dri2_swapbuffers = GL_TRUE; - - intelDRI2Flush(drawable); - drawable->validBuffers = GL_FALSE; - + dri2InvalidateDrawable(drawable); intel_update_renderbuffers(intel->driContext, drawable); } static const struct __DRI2flushExtensionRec intelFlushExtension = { { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, intelDRI2Flush, - intelDRI2FlushInvalidate, + intelDRI2Invalidate, }; static const __DRIextension *intelScreenExtensions[] = { @@ -167,6 +165,11 @@ intel_get_param(__DRIscreen *psp, int param, int *value) } static void +nop_callback(GLuint key, void *data, void *userData) +{ +} + +static void intelDestroyScreen(__DRIscreen * sPriv) { struct intel_screen *intelScreen = sPriv->private; @@ -174,6 +177,12 @@ intelDestroyScreen(__DRIscreen * sPriv) dri_bufmgr_destroy(intelScreen->bufmgr); driDestroyOptionInfo(&intelScreen->optionCache); + /* Some regions may still have references to them at this point, so + * flush the hash table to prevent _mesa_DeleteHashTable() from + * complaining about the hash not being empty; */ + _mesa_HashDeleteAll(intelScreen->named_regions, nop_callback, NULL); + _mesa_DeleteHashTable(intelScreen->named_regions); + FREE(intelScreen); sPriv->private = NULL; } @@ -324,6 +333,8 @@ intel_init_bufmgr(struct intel_screen *intelScreen) else intelScreen->kernel_exec_fencing = GL_FALSE; + intelScreen->named_regions = _mesa_NewHashTable(); + return GL_TRUE; } diff --git a/src/mesa/drivers/dri/intel/intel_screen.h b/src/mesa/drivers/dri/intel/intel_screen.h index c31b836552..1ce476daca 100644 --- a/src/mesa/drivers/dri/intel/intel_screen.h +++ b/src/mesa/drivers/dri/intel/intel_screen.h @@ -47,6 +47,7 @@ struct intel_screen GLboolean no_vbo; dri_bufmgr *bufmgr; GLboolean kernel_exec_fencing; + struct _mesa_HashTable *named_regions; /** * Configuration cache with default values for all contexts diff --git a/src/mesa/drivers/dri/intel/intel_tex_image.c b/src/mesa/drivers/dri/intel/intel_tex_image.c index d63292edd3..bc4e5c6136 100644 --- a/src/mesa/drivers/dri/intel/intel_tex_image.c +++ b/src/mesa/drivers/dri/intel/intel_tex_image.c @@ -748,7 +748,7 @@ intelSetTexBuffer2(__DRIcontext *pDRICtx, GLint target, if (!intelObj) return; - if (!dPriv->validBuffers) + if (dPriv->lastStamp != *dPriv->pStamp) intel_update_renderbuffers(pDRICtx, dPriv); rb = intel_get_renderbuffer(fb, BUFFER_FRONT_LEFT); diff --git a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c index 664632f407..fc5f77b46a 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_bo_state.c @@ -32,7 +32,6 @@ nouveau_bo_marker_emit(GLcontext *ctx, struct nouveau_bo_marker *m, uint32_t flags) { struct nouveau_channel *chan = context_chan(ctx); - struct nouveau_pushbuf *push = chan->pushbuf; uint32_t packet; if (m->gr->bound == NOUVEAU_GROBJ_UNBOUND) @@ -41,11 +40,10 @@ nouveau_bo_marker_emit(GLcontext *ctx, struct nouveau_bo_marker *m, if (MARK_RING(chan, 2, 2)) return GL_FALSE; - push->remaining -= 2; packet = (m->gr->subc << 13) | (1 << 18) | m->mthd; if (flags) { - if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, + if (nouveau_pushbuf_emit_reloc(chan, chan->cur++, m->bo, packet, 0, flags | (m->flags & (NOUVEAU_BO_VRAM | NOUVEAU_BO_GART | @@ -53,10 +51,10 @@ nouveau_bo_marker_emit(GLcontext *ctx, struct nouveau_bo_marker *m, 0, 0)) goto fail; } else { - *(push->cur++) = packet; + *(chan->cur++) = packet; } - if (nouveau_pushbuf_emit_reloc(chan, push->cur++, m->bo, m->data, + if (nouveau_pushbuf_emit_reloc(chan, chan->cur++, m->bo, m->data, m->data2, flags | m->flags, m->vor, m->tor)) goto fail; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_context.c b/src/mesa/drivers/dri/nouveau/nouveau_context.c index b87b8dbdd0..6117f68bcf 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_context.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_context.c @@ -140,6 +140,8 @@ nouveau_update_renderbuffers(__DRIcontext *context, __DRIdrawable *drawable, __DRIbuffer *buffers = NULL; int i = 0, count, ret; + *stamp = *drawable->pStamp; + attachments[i++] = __DRI_BUFFER_FRONT_LEFT; if (fb->Visual.doubleBufferMode) attachments[i++] = __DRI_BUFFER_BACK_LEFT; @@ -218,10 +220,11 @@ nouveau_context_make_current(__DRIcontext *dri_ctx, __DRIdrawable *dri_draw, struct nouveau_context *nctx = dri_ctx->driverPrivate; GLcontext *ctx = &nctx->base; - if (nctx->screen->context != nctx) { - nctx->screen->context = nctx; - BITSET_ONES(nctx->dirty); - } + if (nctx->screen->context == nctx) + return GL_TRUE; + + nctx->screen->context = nctx; + BITSET_ONES(nctx->dirty); /* Ask the X server for new renderbuffers. */ nouveau_update_renderbuffers(dri_ctx, dri_draw, @@ -267,6 +270,28 @@ void nouveau_validate_framebuffer(GLcontext *ctx) { struct nouveau_context *nctx = to_nouveau_context(ctx); + __DRIcontext *dri_ctx = to_nouveau_context(ctx)->dri_context; + __DRIdrawable *dri_draw = dri_ctx->driDrawablePriv; + __DRIdrawable *dri_read = dri_ctx->driReadablePriv; + + if ((ctx->DrawBuffer->Name == 0 && + nctx->drawable.d_stamp != *dri_draw->pStamp) || + (dri_draw != dri_read && + ctx->ReadBuffer->Name == 0 && + nctx->drawable.r_stamp != *dri_read->pStamp)) { + if (nctx->drawable.dirty) + ctx->Driver.Flush(ctx); + + /* Ask the X server for new renderbuffers. */ + nouveau_update_renderbuffers(dri_ctx, dri_draw, + &nctx->drawable.d_stamp); + if (dri_draw != dri_read) + nouveau_update_renderbuffers(dri_ctx, dri_read, + &nctx->drawable.r_stamp); + + if (nouveau_next_dirty_state(ctx) >= 0) + FIRE_RING(context_chan(ctx)); + } /* Someone's planning to draw something really soon. */ nctx->drawable.dirty = GL_TRUE; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_screen.c b/src/mesa/drivers/dri/nouveau/nouveau_screen.c index 6abab8c965..3f9f3a3567 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_screen.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_screen.c @@ -247,7 +247,19 @@ nouveau_destroy_buffer(__DRIdrawable *drawable) (struct gl_framebuffer **)&drawable->driverPrivate, NULL); } +static void +nouveau_drawable_flush(__DRIdrawable *draw) +{ +} + +static const struct __DRI2flushExtensionRec nouveau_flush_extension = { + { __DRI2_FLUSH, __DRI2_FLUSH_VERSION }, + nouveau_drawable_flush, + dri2InvalidateDrawable, +}; + static const __DRIextension *nouveau_screen_extensions[] = { + &nouveau_flush_extension.base, NULL }; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c index 8fa922f422..a1609a0dd5 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_swtnl_t.c @@ -210,7 +210,7 @@ swtnl_flush_vertices(GLcontext *ctx) swtnl_bind_vertices(ctx); while (count) { - push = get_max_vertices(ctx, NULL, chan->pushbuf->remaining); + push = get_max_vertices(ctx, NULL, AVAIL_RING(chan)); push = MIN2(push / 12 * 12, count); count -= push; diff --git a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c index ba1192a170..02c8580760 100644 --- a/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c +++ b/src/mesa/drivers/dri/nouveau/nouveau_vbo_t.c @@ -319,7 +319,7 @@ vbo_draw_vbo(GLcontext *ctx, const struct gl_client_array **arrays, min_index, max_index); } - if (count > get_max_vertices(ctx, ib, chan->pushbuf->remaining)) + if (count > get_max_vertices(ctx, ib, AVAIL_RING(chan))) WAIT_RING(chan, PUSHBUF_DWORDS); BATCH_BEGIN(nvgl_primitive(prims[i].mode)); @@ -355,7 +355,7 @@ vbo_draw_imm(GLcontext *ctx, const struct gl_client_array **arrays, end = start + prims[i].count; if (prims[i].count > get_max_vertices(ctx, ib, - chan->pushbuf->remaining)) + AVAIL_RING(chan))) WAIT_RING(chan, PUSHBUF_DWORDS); BATCH_BEGIN(nvgl_primitive(prims[i].mode)); diff --git a/src/mesa/drivers/dri/r300/r300_draw.c b/src/mesa/drivers/dri/r300/r300_draw.c index 4ae0d6fe48..3efa0e3a16 100644 --- a/src/mesa/drivers/dri/r300/r300_draw.c +++ b/src/mesa/drivers/dri/r300/r300_draw.c @@ -332,7 +332,7 @@ static void r300TranslateAttrib(GLcontext *ctx, GLuint attr, int count, const st { r300ContextPtr r300 = R300_CONTEXT(ctx); struct r300_vertex_buffer *vbuf = &r300->vbuf; - struct vertex_attribute r300_attr; + struct vertex_attribute r300_attr = { 0 }; GLenum type; GLuint stride; diff --git a/src/mesa/drivers/dri/r300/r300_vertprog.c b/src/mesa/drivers/dri/r300/r300_vertprog.c index e6fa57d439..3a8d5fb745 100644 --- a/src/mesa/drivers/dri/r300/r300_vertprog.c +++ b/src/mesa/drivers/dri/r300/r300_vertprog.c @@ -234,7 +234,7 @@ static struct r300_vertex_program *build_program(GLcontext *ctx, struct r300_vertex_program_compiler compiler; vp = _mesa_calloc(sizeof(*vp)); - vp->Base = (struct gl_vertex_program *) _mesa_clone_program(ctx, &mesa_vp->Base); + vp->Base = _mesa_clone_vertex_program(ctx, mesa_vp); _mesa_memcpy(&vp->key, wanted_key, sizeof(vp->key)); rc_init(&compiler.Base); diff --git a/src/mesa/drivers/dri/r600/r700_assembler.c b/src/mesa/drivers/dri/r600/r700_assembler.c index 89adb77bf5..d0059fad2e 100644 --- a/src/mesa/drivers/dri/r600/r700_assembler.c +++ b/src/mesa/drivers/dri/r600/r700_assembler.c @@ -830,6 +830,8 @@ GLboolean assemble_vfetch_instruction(r700_AssemblerBase* pAsm, if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here { //TODO : mini fetch + mega_fetch_count = 0; + is_mega_fetch_flag = 0; } else { @@ -922,6 +924,8 @@ GLboolean assemble_vfetch_instruction2(r700_AssemblerBase* pAsm, if(GL_TRUE == pFetchMethod->bEnableMini) //More conditions here { //TODO : mini fetch + mega_fetch_count = 0; + is_mega_fetch_flag = 0; } else { @@ -2260,7 +2264,7 @@ GLboolean check_vector(r700_AssemblerBase* pAsm, GLboolean assemble_alu_instruction(r700_AssemblerBase *pAsm) { - R700ALUInstruction * alu_instruction_ptr; + R700ALUInstruction * alu_instruction_ptr = NULL; R700ALUInstructionHalfLiteral * alu_instruction_ptr_hl; R700ALUInstructionFullLiteral * alu_instruction_ptr_fl; diff --git a/src/mesa/drivers/dri/r600/r700_chip.c b/src/mesa/drivers/dri/r600/r700_chip.c index e0be74935b..a742dbcf12 100644 --- a/src/mesa/drivers/dri/r600/r700_chip.c +++ b/src/mesa/drivers/dri/r600/r700_chip.c @@ -200,7 +200,8 @@ static void r700SetupVTXConstants(GLcontext * ctx, } else { - nVBsize = paos->count * pStreamDesc->stride; + nVBsize = (paos->count - 1) * pStreamDesc->stride + + pStreamDesc->size * getTypeSize(pStreamDesc->type); } uSQ_VTX_CONSTANT_WORD0_0 = paos->offset; @@ -218,11 +219,11 @@ static void r700SetupVTXConstants(GLcontext * ctx, SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_NORM, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask); } - //else - //{ - // SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_INT, - // SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask); - //} + else + { + SETfield(uSQ_VTX_CONSTANT_WORD2_0, SQ_NUM_FORMAT_SCALED, + SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_shift, SQ_VTX_CONSTANT_WORD2_0__NUM_FORMAT_ALL_mask); + } if(1 == pStreamDesc->_signed) { diff --git a/src/mesa/drivers/dri/r600/r700_vertprog.c b/src/mesa/drivers/dri/r600/r700_vertprog.c index 618f7e1be1..46481cdff4 100644 --- a/src/mesa/drivers/dri/r600/r700_vertprog.c +++ b/src/mesa/drivers/dri/r600/r700_vertprog.c @@ -308,7 +308,7 @@ struct r700_vertex_program* r700TranslateVertexShader(GLcontext *ctx, unsigned int i; vp = _mesa_calloc(sizeof(*vp)); - vp->mesa_program = (struct gl_vertex_program *)_mesa_clone_program(ctx, &mesa_vp->Base); + vp->mesa_program = _mesa_clone_vertex_program(ctx, mesa_vp); if (mesa_vp->IsPositionInvariant) { diff --git a/src/mesa/main/clear.c b/src/mesa/main/clear.c index 4a3c111658..8085bedf1c 100644 --- a/src/mesa/main/clear.c +++ b/src/mesa/main/clear.c @@ -236,7 +236,7 @@ make_color_buffer_mask(GLcontext *ctx, GLint drawbuffer) mask |= BUFFER_BIT_BACK_RIGHT; break; default: - if (drawbuffer < 0 || drawbuffer >= ctx->Const.MaxDrawBuffers) { + if (drawbuffer < 0 || drawbuffer >= (GLint)ctx->Const.MaxDrawBuffers) { mask = INVALID_MASK; } else if (att[BUFFER_COLOR0 + drawbuffer].Renderbuffer) { @@ -306,11 +306,11 @@ _mesa_ClearBufferiv(GLenum buffer, GLint drawbuffer, const GLint *value) * floating point state var. This will not always work. We'll * need a new ctx->Driver.ClearBuffer() hook.... */ - GLfloat clearSave[4]; + GLclampf clearSave[4]; /* save color */ COPY_4V(clearSave, ctx->Color.ClearColor); /* set color */ - COPY_4V(ctx->Color.ClearColor, value); + COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); /* clear buffer(s) */ @@ -365,11 +365,11 @@ _mesa_ClearBufferuiv(GLenum buffer, GLint drawbuffer, const GLuint *value) * floating point state var. This will not always work. We'll * need a new ctx->Driver.ClearBuffer() hook.... */ - GLfloat clearSave[4]; + GLclampf clearSave[4]; /* save color */ COPY_4V(clearSave, ctx->Color.ClearColor); /* set color */ - COPY_4V(ctx->Color.ClearColor, value); + COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); /* clear buffer(s) */ @@ -423,7 +423,7 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) * XXX in the future we may have a new ctx->Driver.ClearBuffer() * hook instead. */ - const GLfloat clearSave = ctx->Depth.Clear; + const GLclampd clearSave = ctx->Depth.Clear; ctx->Depth.Clear = *value; if (ctx->Driver.ClearDepth) ctx->Driver.ClearDepth(ctx, *value); @@ -443,11 +443,11 @@ _mesa_ClearBufferfv(GLenum buffer, GLint drawbuffer, const GLfloat *value) return; } else if (mask) { - GLfloat clearSave[4]; + GLclampf clearSave[4]; /* save color */ COPY_4V(clearSave, ctx->Color.ClearColor); /* set color */ - COPY_4V(ctx->Color.ClearColor, value); + COPY_4V_CAST(ctx->Color.ClearColor, value, GLclampf); if (ctx->Driver.ClearColor) ctx->Driver.ClearColor(ctx, ctx->Color.ClearColor); /* clear buffer(s) */ @@ -503,7 +503,7 @@ _mesa_ClearBufferfi(GLenum buffer, GLint drawbuffer, { /* save current clear values */ - const GLfloat clearDepthSave = ctx->Depth.Clear; + const GLclampd clearDepthSave = ctx->Depth.Clear; const GLuint clearStencilSave = ctx->Stencil.Clear; /* set new clear values */ diff --git a/src/mesa/main/extensions.c b/src/mesa/main/extensions.c index e1320224a8..87c1fac28a 100644 --- a/src/mesa/main/extensions.c +++ b/src/mesa/main/extensions.c @@ -50,8 +50,7 @@ static const struct { { OFF, "GL_ARB_depth_clamp", F(ARB_depth_clamp) }, { ON, "GL_ARB_draw_buffers", F(ARB_draw_buffers) }, { OFF, "GL_ARB_draw_elements_base_vertex", F(ARB_draw_elements_base_vertex) }, - /* TODO: uncomment the following line once GLSL layout(...) support is implemented */ - /* { OFF, "GL_ARB_fragment_coord_conventions", F(ARB_fragment_coord_conventions) }, */ + { OFF, "GL_ARB_fragment_coord_conventions", F(ARB_fragment_coord_conventions) }, { OFF, "GL_ARB_fragment_program", F(ARB_fragment_program) }, { OFF, "GL_ARB_fragment_program_shadow", F(ARB_fragment_program_shadow) }, { OFF, "GL_ARB_fragment_shader", F(ARB_fragment_shader) }, @@ -133,6 +132,7 @@ static const struct { { ON, "GL_EXT_texture", F(EXT_texture) }, { ON, "GL_EXT_texture3D", F(EXT_texture3D) }, { OFF, "GL_EXT_texture_compression_s3tc", F(EXT_texture_compression_s3tc) }, + { OFF, "GL_EXT_texture_cube_map", F(ARB_texture_cube_map) }, { ON, "GL_EXT_texture_edge_clamp", F(SGIS_texture_edge_clamp) }, { OFF, "GL_EXT_texture_env_add", F(EXT_texture_env_add) }, { OFF, "GL_EXT_texture_env_combine", F(EXT_texture_env_combine) }, @@ -211,6 +211,7 @@ _mesa_enable_sw_extensions(GLcontext *ctx) ctx->Extensions.ARB_depth_texture = GL_TRUE; /*ctx->Extensions.ARB_draw_buffers = GL_TRUE;*/ ctx->Extensions.ARB_draw_elements_base_vertex = GL_TRUE; + ctx->Extensions.ARB_fragment_coord_conventions = GL_TRUE; #if FEATURE_ARB_fragment_program ctx->Extensions.ARB_fragment_program = GL_TRUE; ctx->Extensions.ARB_fragment_program_shadow = GL_TRUE; diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c index 2724774ca2..60fef552c4 100644 --- a/src/mesa/main/get.c +++ b/src/mesa/main/get.c @@ -7,7 +7,6 @@ #include "context.h" #include "enable.h" #include "extensions.h" -#include "fbobject.h" #include "get.h" #include "macros.h" #include "mtypes.h" diff --git a/src/mesa/main/get_gen.py b/src/mesa/main/get_gen.py index 9ae3ce0096..64aa2aca26 100644 --- a/src/mesa/main/get_gen.py +++ b/src/mesa/main/get_gen.py @@ -27,6 +27,7 @@ import string +import sys GLint = 1 @@ -1134,7 +1135,7 @@ def EmitGetFunction(stateVars, returnType, indexed): elif returnType == GLint64: function = "GetInteger64v" else: - abort() + sys.exit(1) if returnType == GLint64: print "#if FEATURE_ARB_sync" @@ -1225,7 +1226,6 @@ def EmitHeader(): #include "context.h" #include "enable.h" #include "extensions.h" -#include "fbobject.h" #include "get.h" #include "macros.h" #include "mtypes.h" diff --git a/src/mesa/main/hash.c b/src/mesa/main/hash.c index 08c64568c8..fdfbe6b4f4 100644 --- a/src/mesa/main/hash.c +++ b/src/mesa/main/hash.c @@ -128,7 +128,7 @@ _mesa_DeleteHashTable(struct _mesa_HashTable *table) * \return pointer to user's data or NULL if key not in table */ void * -_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key) +_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key) { GLuint pos; const struct HashEntry *entry; @@ -137,13 +137,16 @@ _mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key) assert(key); pos = HASH_FUNC(key); + _glthread_LOCK_MUTEX(table->Mutex); entry = table->Table[pos]; while (entry) { if (entry->Key == key) { - return entry->Data; + _glthread_UNLOCK_MUTEX(table->Mutex); + return entry->Data; } entry = entry->Next; } + _glthread_UNLOCK_MUTEX(table->Mutex); return NULL; } @@ -191,10 +194,12 @@ _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data) /* alloc and insert new table entry */ entry = MALLOC_STRUCT(HashEntry); - entry->Key = key; - entry->Data = data; - entry->Next = table->Table[pos]; - table->Table[pos] = entry; + if (entry) { + entry->Key = key; + entry->Data = data; + entry->Next = table->Table[pos]; + table->Table[pos] = entry; + } _glthread_UNLOCK_MUTEX(table->Mutex); } diff --git a/src/mesa/main/hash.h b/src/mesa/main/hash.h index d18db76abe..4f916f9d01 100644 --- a/src/mesa/main/hash.h +++ b/src/mesa/main/hash.h @@ -39,7 +39,7 @@ extern struct _mesa_HashTable *_mesa_NewHashTable(void); extern void _mesa_DeleteHashTable(struct _mesa_HashTable *table); -extern void *_mesa_HashLookup(const struct _mesa_HashTable *table, GLuint key); +extern void *_mesa_HashLookup(struct _mesa_HashTable *table, GLuint key); extern void _mesa_HashInsert(struct _mesa_HashTable *table, GLuint key, void *data); diff --git a/src/mesa/main/image.c b/src/mesa/main/image.c index 81993e7063..468f2a9b21 100644 --- a/src/mesa/main/image.c +++ b/src/mesa/main/image.c @@ -5662,7 +5662,7 @@ clip_right_or_top(GLint *srcX0, GLint *srcX1, /* chop off [t, 1] part */ ASSERT(t >= 0.0 && t <= 1.0); *dstX1 = maxValue; - bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; + bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; *srcX1 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias); } else if (*dstX0 > maxValue) { @@ -5672,7 +5672,7 @@ clip_right_or_top(GLint *srcX0, GLint *srcX1, /* chop off [t, 1] part */ ASSERT(t >= 0.0 && t <= 1.0); *dstX0 = maxValue; - bias = (*srcX0 < *srcX1) ? -0.5 : 0.5; + bias = (*srcX0 < *srcX1) ? -0.5F : 0.5F; *srcX0 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias); } } @@ -5695,7 +5695,7 @@ clip_left_or_bottom(GLint *srcX0, GLint *srcX1, /* chop off [0, t] part */ ASSERT(t >= 0.0 && t <= 1.0); *dstX0 = minValue; - bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; /* flipped??? */ + bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; /* flipped??? */ *srcX0 = *srcX0 + (GLint) (t * (*srcX1 - *srcX0) + bias); } else if (*dstX1 < minValue) { @@ -5705,7 +5705,7 @@ clip_left_or_bottom(GLint *srcX0, GLint *srcX1, /* chop off [0, t] part */ ASSERT(t >= 0.0 && t <= 1.0); *dstX1 = minValue; - bias = (*srcX0 < *srcX1) ? 0.5 : -0.5; + bias = (*srcX0 < *srcX1) ? 0.5F : -0.5F; *srcX1 = *srcX1 + (GLint) (t * (*srcX0 - *srcX1) + bias); } } diff --git a/src/mesa/main/imports.h b/src/mesa/main/imports.h index 3843f50036..e3d2ac9b42 100644 --- a/src/mesa/main/imports.h +++ b/src/mesa/main/imports.h @@ -412,13 +412,19 @@ _mesa_is_pow_two(int x) * Source for the fallback implementation is * Sean Eron Anderson's webpage "Bit Twiddling Hacks" * http://graphics.stanford.edu/~seander/bithacks.html + * + * When using builtin function have to do some work + * for case when passed values 1 to prevent hiting + * undefined result from __builtin_clz. Undefined + * results would be different depending on optimization + * level used for build. */ static INLINE int32_t _mesa_next_pow_two_32(uint32_t x) { #ifdef __GNUC__ - x--; - return 1 << ((__builtin_clz(x) ^ 31) + 1); + uint32_t y = (x != 1); + return (1 + y) << ((__builtin_clz(x - y) ^ 31) ); #else x--; x |= x >> 1; @@ -435,11 +441,11 @@ static INLINE int64_t _mesa_next_pow_two_64(uint64_t x) { #ifdef __GNUC__ - x--; + uint64_t y = (x != 1); if (sizeof(x) == sizeof(long)) - return 1 << ((__builtin_clzl(x) ^ 63) + 1); + return (1 + y) << ((__builtin_clzl(x - y) ^ 63)); else - return 1 << ((__builtin_clzll(x) ^ 63) + 1); + return (1 + y) << ((__builtin_clzll(x - y) ^ 63)); #else x--; x |= x >> 1; diff --git a/src/mesa/main/macros.h b/src/mesa/main/macros.h index 55578adf83..38a97fdb18 100644 --- a/src/mesa/main/macros.h +++ b/src/mesa/main/macros.h @@ -83,14 +83,14 @@ extern GLfloat _mesa_ubyte_to_float_color_tab[256]; /** Convert GLuint in [0,4294967295] to GLfloat in [0.0,1.0] */ -#define UINT_TO_FLOAT(U) ((GLfloat) (U) * (1.0F / 4294967295.0)) +#define UINT_TO_FLOAT(U) ((GLfloat) ((U) * (1.0F / 4294967295.0))) /** Convert GLfloat in [0.0,1.0] to GLuint in [0,4294967295] */ #define FLOAT_TO_UINT(X) ((GLuint) ((X) * 4294967295.0)) /** Convert GLint in [-2147483648,2147483647] to GLfloat in [-1.0,1.0] */ -#define INT_TO_FLOAT(I) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0)) +#define INT_TO_FLOAT(I) ((GLfloat) ((2.0F * (I) + 1.0F) * (1.0F/4294967294.0))) /** Convert GLfloat in [-1.0,1.0] to GLint in [-2147483648,2147483647] */ /* causes overflow: diff --git a/src/mesa/main/texgetimage.c b/src/mesa/main/texgetimage.c index 66d01c15d0..6b3355a7ec 100644 --- a/src/mesa/main/texgetimage.c +++ b/src/mesa/main/texgetimage.c @@ -590,7 +590,7 @@ getteximage_error_check(GLcontext *ctx, GLenum target, GLint level, { struct gl_texture_object *texObj; struct gl_texture_image *texImage; - const GLuint maxLevels = _mesa_max_texture_levels(ctx, target); + const GLint maxLevels = _mesa_max_texture_levels(ctx, target); GLenum baseFormat; if (maxLevels == 0) { @@ -776,7 +776,7 @@ getcompressedteximage_error_check(GLcontext *ctx, GLenum target, GLint level, { struct gl_texture_object *texObj; struct gl_texture_image *texImage; - const GLuint maxLevels = _mesa_max_texture_levels(ctx, target); + const GLint maxLevels = _mesa_max_texture_levels(ctx, target); if (maxLevels == 0) { _mesa_error(ctx, GL_INVALID_ENUM, "glGetCompressedTexImage(target=0x%x)", diff --git a/src/mesa/main/texstore.c b/src/mesa/main/texstore.c index fcd0a56d76..78612b0856 100644 --- a/src/mesa/main/texstore.c +++ b/src/mesa/main/texstore.c @@ -2678,7 +2678,7 @@ _mesa_texstore_signed_rgba8888(TEXSTORE_PARAMS) static GLboolean _mesa_texstore_z24_s8(TEXSTORE_PARAMS) { - const GLfloat depthScale = (GLfloat) 0xffffff; + const GLuint depthScale = 0xffffff; const GLint srcRowStride = _mesa_image_row_stride(srcPacking, srcWidth, srcFormat, srcType) / sizeof(GLuint); @@ -2752,7 +2752,7 @@ _mesa_texstore_z24_s8(TEXSTORE_PARAMS) _mesa_unpack_depth_span(ctx, srcWidth, GL_UNSIGNED_INT_24_8_EXT, /* dst type */ dstRow, /* dst addr */ - (GLuint) depthScale, + depthScale, srcType, src, srcPacking); /* get the 8-bit stencil values */ _mesa_unpack_stencil_span(ctx, srcWidth, diff --git a/src/mesa/shader/nvprogram.c b/src/mesa/shader/nvprogram.c index 87f295e39a..c3b10f5d9b 100644 --- a/src/mesa/shader/nvprogram.c +++ b/src/mesa/shader/nvprogram.c @@ -570,15 +570,15 @@ _mesa_setup_nv_temporary_count(GLcontext *ctx, struct gl_program *program) inst->DstReg.Index + 1); } if (inst->SrcReg[0].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2(program->NumTemporaries, + program->NumTemporaries = MAX2((GLint)program->NumTemporaries, inst->SrcReg[0].Index + 1); } if (inst->SrcReg[1].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2(program->NumTemporaries, + program->NumTemporaries = MAX2((GLint)program->NumTemporaries, inst->SrcReg[1].Index + 1); } if (inst->SrcReg[2].File == PROGRAM_TEMPORARY) { - program->NumTemporaries = MAX2(program->NumTemporaries, + program->NumTemporaries = MAX2((GLint)program->NumTemporaries, inst->SrcReg[2].Index + 1); } } diff --git a/src/mesa/shader/prog_execute.c b/src/mesa/shader/prog_execute.c index 7781cb3f7f..ee422e7ec8 100644 --- a/src/mesa/shader/prog_execute.c +++ b/src/mesa/shader/prog_execute.c @@ -599,13 +599,13 @@ store_vector4ui(const struct prog_instruction *inst, if (inst->CondUpdate) { if (writeMask & WRITEMASK_X) - machine->CondCodes[0] = generate_cc(value[0]); + machine->CondCodes[0] = generate_cc((float)value[0]); if (writeMask & WRITEMASK_Y) - machine->CondCodes[1] = generate_cc(value[1]); + machine->CondCodes[1] = generate_cc((float)value[1]); if (writeMask & WRITEMASK_Z) - machine->CondCodes[2] = generate_cc(value[2]); + machine->CondCodes[2] = generate_cc((float)value[2]); if (writeMask & WRITEMASK_W) - machine->CondCodes[3] = generate_cc(value[3]); + 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]), @@ -1000,7 +1000,7 @@ _mesa_execute_program(GLcontext * ctx, val = -FLT_MAX; } else { - val = log(a[0]) * 1.442695F; + val = (float)(log(a[0]) * 1.442695F); } result[0] = result[1] = result[2] = result[3] = val; store_vector4(inst, machine, result); @@ -1065,7 +1065,7 @@ _mesa_execute_program(GLcontext * ctx, /* The fast LOG2 macro doesn't meet the precision * requirements. */ - q[2] = (log(t[0]) * 1.442695F); + q[2] = (float)(log(t[0]) * 1.442695F); } } else { @@ -1780,15 +1780,10 @@ _mesa_execute_program(GLcontext * ctx, break; case OPCODE_PRINT: { - if (inst->SrcReg[0].File != -1) { - GLfloat a[4]; - fetch_vector4(&inst->SrcReg[0], machine, a); - _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, - a[0], a[1], a[2], a[3]); - } - else { - _mesa_printf("%s\n", (const char *) inst->Data); - } + GLfloat a[4]; + fetch_vector4(&inst->SrcReg[0], machine, a); + _mesa_printf("%s%g, %g, %g, %g\n", (const char *) inst->Data, + a[0], a[1], a[2], a[3]); } break; case OPCODE_END: diff --git a/src/mesa/shader/prog_parameter.c b/src/mesa/shader/prog_parameter.c index 5822510701..d4970c4e44 100644 --- a/src/mesa/shader/prog_parameter.c +++ b/src/mesa/shader/prog_parameter.c @@ -209,7 +209,7 @@ _mesa_add_named_constant(struct gl_program_parameter_list *paramList, { /* first check if this is a duplicate constant */ GLint pos; - for (pos = 0; pos < paramList->NumParameters; pos++) { + for (pos = 0; pos < (GLint)paramList->NumParameters; pos++) { const GLfloat *pvals = paramList->ParameterValues[pos]; if (pvals[0] == values[0] && pvals[1] == values[1] && diff --git a/src/mesa/shader/program.c b/src/mesa/shader/program.c index aaf5f96e2a..18ef6d5ccf 100644 --- a/src/mesa/shader/program.c +++ b/src/mesa/shader/program.c @@ -505,6 +505,8 @@ _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog) struct gl_fragment_program *fpc = (struct gl_fragment_program *) clone; fpc->FogOption = fp->FogOption; fpc->UsesKill = fp->UsesKill; + fpc->OriginUpperLeft = fp->OriginUpperLeft; + fpc->PixelCenterInteger = fp->PixelCenterInteger; } break; default: diff --git a/src/mesa/shader/program.h b/src/mesa/shader/program.h index 0187a2c55f..af9f4170d1 100644 --- a/src/mesa/shader/program.h +++ b/src/mesa/shader/program.h @@ -108,6 +108,22 @@ _mesa_reference_fragprog(GLcontext *ctx, extern struct gl_program * _mesa_clone_program(GLcontext *ctx, const struct gl_program *prog); +static INLINE struct gl_vertex_program * +_mesa_clone_vertex_program(GLcontext *ctx, + const struct gl_vertex_program *prog) +{ + return (struct gl_vertex_program *) _mesa_clone_program(ctx, &prog->Base); +} + + +static INLINE struct gl_fragment_program * +_mesa_clone_fragment_program(GLcontext *ctx, + const struct gl_fragment_program *prog) +{ + return (struct gl_fragment_program *) _mesa_clone_program(ctx, &prog->Base); +} + + extern GLboolean _mesa_insert_instructions(struct gl_program *prog, GLuint start, GLuint count); diff --git a/src/mesa/shader/slang/slang_codegen.c b/src/mesa/shader/slang/slang_codegen.c index 83098b7350..fe4bddf9ad 100644 --- a/src/mesa/shader/slang/slang_codegen.c +++ b/src/mesa/shader/slang/slang_codegen.c @@ -3117,7 +3117,7 @@ _slang_can_unroll_for_loop(slang_assemble_ctx * A, const slang_operation *oper) if (start >= end) return GL_FALSE; /* degenerate case */ - if (end - start > MAX_FOR_LOOP_UNROLL_ITERATIONS) { + if ((GLuint)(end - start) > MAX_FOR_LOOP_UNROLL_ITERATIONS) { slang_info_log_print(A->log, "Note: 'for (%s=%d; %s<%d; ++%s)' is too" " many iterations to unroll", diff --git a/src/mesa/shader/slang/slang_compile.c b/src/mesa/shader/slang/slang_compile.c index 852274119c..33964e0c3b 100644 --- a/src/mesa/shader/slang/slang_compile.c +++ b/src/mesa/shader/slang/slang_compile.c @@ -239,7 +239,7 @@ parse_general_number(slang_parse_ctx *ctx, float *number) } parse_identifier_str(ctx, &flt); - flt = strdup(flt); + flt = _mesa_strdup(flt); if (!flt) { return 0; } @@ -636,6 +636,38 @@ parse_type_centroid(slang_parse_ctx * C, slang_type_centroid *centroid) } +/* Layout qualifiers */ +#define LAYOUT_QUALIFIER_NONE 0 +#define LAYOUT_QUALIFIER_UPPER_LEFT 1 +#define LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER 2 + +static int +parse_layout_qualifiers(slang_parse_ctx * C, slang_layout_qualifier *layout) +{ + *layout = 0x0; + + /* the layout qualifiers come as a list of LAYOUT_QUALIFER_x tokens, + * terminated by LAYOUT_QUALIFIER_NONE. + */ + while (1) { + GLuint c = *C->I++; + switch (c) { + case LAYOUT_QUALIFIER_NONE: + /* end of list of qualifiers */ + return 1; + case LAYOUT_QUALIFIER_UPPER_LEFT: + *layout |= SLANG_LAYOUT_UPPER_LEFT_BIT; + break; + case LAYOUT_QUALIFIER_PIXEL_CENTER_INTEGER: + *layout |= SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT; + break; + default: + assert(0 && "Bad layout qualifier"); + } + } +} + + /* type qualifier */ #define TYPE_QUALIFIER_NONE 0 #define TYPE_QUALIFIER_CONST 1 @@ -907,9 +939,12 @@ static int parse_fully_specified_type(slang_parse_ctx * C, slang_output_ctx * O, slang_fully_specified_type * type) { + if (!parse_layout_qualifiers(C, &type->layout)) + RETURN0; + if (!parse_type_variant(C, &type->variant)) RETURN0; - + if (!parse_type_centroid(C, &type->centroid)) RETURN0; @@ -2029,6 +2064,30 @@ initialize_global(slang_assemble_ctx * A, slang_variable * var) /** + * Check if it's OK to re-declare a variable with the given new type. + * This happens when applying layout qualifiers to gl_FragCoord or + * (re)setting an array size. + * If redeclaration is OK, return a pointer to the incoming variable + * updated with new type info. Else return NULL; + */ +static slang_variable * +redeclare_variable(slang_variable *var, + const slang_fully_specified_type *type) +{ + if (slang_fully_specified_types_compatible(&var->type, type)) { + /* replace orig var layout with new layout */ + var->type.layout = type->layout; + + /* XXX there may be other type updates in the future here */ + + return var; + } + else + return NULL; +} + + +/** * Parse the initializer for a variable declaration. */ static int @@ -2036,7 +2095,7 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, const slang_fully_specified_type * type) { GET_CURRENT_CONTEXT(ctx); /* a hack */ - slang_variable *var; + slang_variable *var = NULL, *prevDecl; slang_atom a_name; /* empty init declatator (without name, e.g. "float ;") */ @@ -2046,29 +2105,41 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, a_name = parse_identifier(C); /* check if name is already in this scope */ - if (_slang_variable_locate(O->vars, a_name, GL_FALSE)) { - slang_info_log_error(C->L, + prevDecl = _slang_variable_locate(O->vars, a_name, C->global_scope); + if (prevDecl) { + /* A var with this name has already been declared. + * Check if redeclaring the var with a different type/layout is legal. + */ + if (C->global_scope) { + var = redeclare_variable(prevDecl, type); + } + if (!var) { + slang_info_log_error(C->L, "declaration of '%s' conflicts with previous declaration", (char *) a_name); - RETURN0; + RETURN0; + } } - /* make room for the new variable and initialize it */ - var = slang_variable_scope_grow(O->vars); if (!var) { - slang_info_log_memory(C->L); - RETURN0; - } + /* make room for a new variable and initialize it */ + var = slang_variable_scope_grow(O->vars); + if (!var) { + slang_info_log_memory(C->L); + RETURN0; + } - /* copy the declarator type qualifier/etc info, parse the identifier */ - var->type.qualifier = type->qualifier; - var->type.centroid = type->centroid; - var->type.precision = type->precision; - var->type.variant = type->variant; - var->type.array_len = type->array_len; - var->a_name = a_name; - if (var->a_name == SLANG_ATOM_NULL) - RETURN0; + /* copy the declarator type qualifier/etc info, parse the identifier */ + var->type.qualifier = type->qualifier; + var->type.centroid = type->centroid; + var->type.precision = type->precision; + var->type.variant = type->variant; + var->type.layout = type->layout; + var->type.array_len = type->array_len; + var->a_name = a_name; + if (var->a_name == SLANG_ATOM_NULL) + RETURN0; + } switch (*C->I++) { case VARIABLE_NONE: @@ -2169,6 +2240,21 @@ parse_init_declarator(slang_parse_ctx * C, slang_output_ctx * O, RETURN0; } } + + if (var->type.qualifier == SLANG_QUAL_FIXEDINPUT && + var->a_name == slang_atom_pool_atom(C->atoms, "gl_FragCoord")) { + /* set the program's PixelCenterInteger, OriginUpperLeft fields */ + struct gl_fragment_program *fragProg = + (struct gl_fragment_program *) O->program; + + if (var->type.layout & SLANG_LAYOUT_UPPER_LEFT_BIT) { + fragProg->OriginUpperLeft = GL_TRUE; + } + if (var->type.layout & SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT) { + fragProg->PixelCenterInteger = GL_TRUE; + } + } + return 1; } @@ -2615,6 +2701,11 @@ compile_with_grammar(const char *source, return GL_FALSE; } + if (type == SLANG_UNIT_FRAGMENT_SHADER) { + sl_pp_context_add_extension(context, "GL_ARB_fragment_coord_conventions"); + } + + #if FEATURE_es2_glsl if (sl_pp_context_add_predefined(context, "GL_ES", "1") || sl_pp_context_add_predefined(context, "GL_FRAGMENT_PRECISION_HIGH", "1")) { diff --git a/src/mesa/shader/slang/slang_emit.c b/src/mesa/shader/slang/slang_emit.c index c9ecbd275b..0f670360ee 100644 --- a/src/mesa/shader/slang/slang_emit.c +++ b/src/mesa/shader/slang/slang_emit.c @@ -1122,6 +1122,8 @@ emit_clamp(slang_emit_info *emitInfo, slang_ir_node *n) return inst; } } +#else + (void) inst; #endif if (!alloc_node_storage(emitInfo, n, n->Children[0]->Store->Size)) diff --git a/src/mesa/shader/slang/slang_link.c b/src/mesa/shader/slang/slang_link.c index df524ce078..75b0022b56 100644 --- a/src/mesa/shader/slang/slang_link.c +++ b/src/mesa/shader/slang/slang_link.c @@ -773,7 +773,7 @@ _slang_link(GLcontext *ctx, _mesa_reference_vertprog(ctx, &shProg->VertexProgram, NULL); if (vertProg) { struct gl_vertex_program *linked_vprog = - vertex_program(_mesa_clone_program(ctx, &vertProg->Base)); + _mesa_clone_vertex_program(ctx, vertProg); shProg->VertexProgram = linked_vprog; /* refcount OK */ /* vertex program ID not significant; just set Id for debugging purposes */ shProg->VertexProgram->Base.Id = shProg->Name; @@ -783,7 +783,7 @@ _slang_link(GLcontext *ctx, _mesa_reference_fragprog(ctx, &shProg->FragmentProgram, NULL); if (fragProg) { struct gl_fragment_program *linked_fprog = - fragment_program(_mesa_clone_program(ctx, &fragProg->Base)); + _mesa_clone_fragment_program(ctx, fragProg); shProg->FragmentProgram = linked_fprog; /* refcount OK */ /* vertex program ID not significant; just set Id for debugging purposes */ shProg->FragmentProgram->Base.Id = shProg->Name; diff --git a/src/mesa/shader/slang/slang_typeinfo.c b/src/mesa/shader/slang/slang_typeinfo.c index 4a48bc8b8e..a96f2fb4c2 100644 --- a/src/mesa/shader/slang/slang_typeinfo.c +++ b/src/mesa/shader/slang/slang_typeinfo.c @@ -258,6 +258,7 @@ slang_fully_specified_type_copy(slang_fully_specified_type * x, z.precision = y->precision; z.variant = y->variant; z.centroid = y->centroid; + z.layout = y->layout; z.array_len = y->array_len; if (!slang_type_specifier_copy(&z.specifier, &y->specifier)) { slang_fully_specified_type_destruct(&z); @@ -269,6 +270,32 @@ slang_fully_specified_type_copy(slang_fully_specified_type * x, } +/** + * Test if two fully specified types are compatible. This is a bit + * looser than testing for equality. We don't check the precision, + * variant, centroid, etc. information. + * XXX this may need some tweaking. + */ +GLboolean +slang_fully_specified_types_compatible(const slang_fully_specified_type * x, + const slang_fully_specified_type * y) +{ + if (!slang_type_specifier_equal(&x->specifier, &y->specifier)) + return GL_FALSE; + + if (x->qualifier == SLANG_QUAL_FIXEDINPUT && + y->qualifier == SLANG_QUAL_VARYING) + ; /* ok */ + else if (x->qualifier != y->qualifier) + return GL_FALSE; + + /* Note: don't compare precision, variant, centroid */ + + /* XXX array length? */ + + return GL_TRUE; +} + GLvoid slang_type_specifier_ctr(slang_type_specifier * self) diff --git a/src/mesa/shader/slang/slang_typeinfo.h b/src/mesa/shader/slang/slang_typeinfo.h index e6fecd350a..aa5f14ebc7 100644 --- a/src/mesa/shader/slang/slang_typeinfo.h +++ b/src/mesa/shader/slang/slang_typeinfo.h @@ -68,6 +68,18 @@ typedef enum slang_type_centroid_ } slang_type_centroid; +/** + * These only apply to gl_FragCoord, but other layout qualifiers may + * appear in the future. + */ +typedef enum slang_layout_qualifier_ +{ + SLANG_LAYOUT_NONE = 0x0, + SLANG_LAYOUT_UPPER_LEFT_BIT = 0x1, + SLANG_LAYOUT_PIXEL_CENTER_INTEGER_BIT = 0x2 +} slang_layout_qualifier; + + typedef enum slang_type_qualifier_ { SLANG_QUAL_NONE, @@ -170,8 +182,8 @@ slang_type_specifier_equal(const slang_type_specifier *, extern GLboolean -slang_type_specifier_compatible(const slang_type_specifier * x, - const slang_type_specifier * y); +slang_type_specifier_compatible(const slang_type_specifier *x, + const slang_type_specifier *y); typedef struct slang_fully_specified_type_ @@ -181,6 +193,7 @@ typedef struct slang_fully_specified_type_ slang_type_precision precision; slang_type_variant variant; slang_type_centroid centroid; + slang_layout_qualifier layout; GLint array_len; /**< -1 if not an array type */ } slang_fully_specified_type; @@ -194,6 +207,9 @@ extern int slang_fully_specified_type_copy(slang_fully_specified_type *, const slang_fully_specified_type *); +GLboolean +slang_fully_specified_types_compatible(const slang_fully_specified_type * x, + const slang_fully_specified_type * y); typedef struct slang_typeinfo_ diff --git a/src/mesa/sources.mak b/src/mesa/sources.mak index 12d4c2831d..354331955a 100644 --- a/src/mesa/sources.mak +++ b/src/mesa/sources.mak @@ -204,7 +204,6 @@ STATETRACKER_SOURCES = \ state_tracker/st_cb_readpixels.c \ state_tracker/st_cb_strings.c \ state_tracker/st_cb_texture.c \ - state_tracker/st_cb_viewport.c \ state_tracker/st_context.c \ state_tracker/st_debug.c \ state_tracker/st_draw.c \ diff --git a/src/mesa/state_tracker/st_atom.c b/src/mesa/state_tracker/st_atom.c index 73df44d198..6a7ebff6ca 100644 --- a/src/mesa/state_tracker/st_atom.c +++ b/src/mesa/state_tracker/st_atom.c @@ -35,7 +35,8 @@ #include "st_cb_bitmap.h" #include "st_program.h" - +#include "pipe/p_context.h" + /** * This is used to initialize st->atoms[]. @@ -135,6 +136,10 @@ void st_validate_state( struct st_context *st ) check_program_state( st ); + if (st->pipe->screen->update_buffer) + st->pipe->screen->update_buffer(st->pipe->screen, + st->pipe->priv); + if (state->st == 0) return; diff --git a/src/mesa/state_tracker/st_atom_depth.c b/src/mesa/state_tracker/st_atom_depth.c index 88b80a07fc..3c07afba9a 100644 --- a/src/mesa/state_tracker/st_atom_depth.c +++ b/src/mesa/state_tracker/st_atom_depth.c @@ -94,9 +94,11 @@ static void update_depth_stencil_alpha(struct st_context *st) { struct pipe_depth_stencil_alpha_state *dsa = &st->state.depth_stencil; + struct pipe_stencil_ref sr; GLcontext *ctx = st->ctx; memset(dsa, 0, sizeof(*dsa)); + memset(&sr, 0, sizeof(sr)); if (ctx->Depth.Test && ctx->DrawBuffer->Visual.depthBits > 0) { dsa->depth.enabled = 1; @@ -110,9 +112,9 @@ update_depth_stencil_alpha(struct st_context *st) dsa->stencil[0].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[0]); dsa->stencil[0].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[0]); dsa->stencil[0].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[0]); - dsa->stencil[0].ref_value = ctx->Stencil.Ref[0] & 0xff; dsa->stencil[0].valuemask = ctx->Stencil.ValueMask[0] & 0xff; dsa->stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff; + sr.ref_value[0] = ctx->Stencil.Ref[0] & 0xff; if (ctx->Stencil._TestTwoSide) { const GLuint back = ctx->Stencil._BackFace; @@ -121,13 +123,17 @@ update_depth_stencil_alpha(struct st_context *st) dsa->stencil[1].fail_op = gl_stencil_op_to_pipe(ctx->Stencil.FailFunc[back]); dsa->stencil[1].zfail_op = gl_stencil_op_to_pipe(ctx->Stencil.ZFailFunc[back]); dsa->stencil[1].zpass_op = gl_stencil_op_to_pipe(ctx->Stencil.ZPassFunc[back]); - dsa->stencil[1].ref_value = ctx->Stencil.Ref[back] & 0xff; dsa->stencil[1].valuemask = ctx->Stencil.ValueMask[back] & 0xff; dsa->stencil[1].writemask = ctx->Stencil.WriteMask[back] & 0xff; + sr.ref_value[1] = ctx->Stencil.Ref[back] & 0xff; } else { + /* This should be unnecessary. Drivers must not expect this to + * contain valid data, except the enabled bit + */ dsa->stencil[1] = dsa->stencil[0]; dsa->stencil[1].enabled = 0; + sr.ref_value[1] = sr.ref_value[0]; } } @@ -138,6 +144,7 @@ update_depth_stencil_alpha(struct st_context *st) } cso_set_depth_stencil_alpha(st->cso_context, dsa); + cso_set_stencil_ref(st->cso_context, &sr); } diff --git a/src/mesa/state_tracker/st_atom_sampler.c b/src/mesa/state_tracker/st_atom_sampler.c index 9d63f1c6ab..a8262a5e1a 100644 --- a/src/mesa/state_tracker/st_atom_sampler.c +++ b/src/mesa/state_tracker/st_atom_sampler.c @@ -211,7 +211,7 @@ update_samplers(struct st_context *st) teximg ? teximg->_BaseFormat : GL_RGBA, sampler->border_color); - sampler->max_anisotropy = texobj->MaxAnisotropy; + sampler->max_anisotropy = (texobj->MaxAnisotropy == 1.0 ? 0 : (GLuint)texobj->MaxAnisotropy); /* only care about ARB_shadow, not SGI shadow */ if (texobj->CompareMode == GL_COMPARE_R_TO_TEXTURE) { diff --git a/src/mesa/state_tracker/st_atom_shader.c b/src/mesa/state_tracker/st_atom_shader.c index ea16719ba0..ad151edf3b 100644 --- a/src/mesa/state_tracker/st_atom_shader.c +++ b/src/mesa/state_tracker/st_atom_shader.c @@ -59,7 +59,7 @@ static void translate_fp(struct st_context *st, struct st_fragment_program *stfp) { - if (!stfp->state.tokens) { + if (!stfp->tgsi.tokens) { assert(stfp->Base.Base.NumInstructions > 0); st_translate_fragment_program(st, stfp); diff --git a/src/mesa/state_tracker/st_cb_clear.c b/src/mesa/state_tracker/st_cb_clear.c index 0c7bcb8597..898c32293d 100644 --- a/src/mesa/state_tracker/st_cb_clear.c +++ b/src/mesa/state_tracker/st_cb_clear.c @@ -215,6 +215,7 @@ clear_with_quad(GLcontext *ctx, */ cso_save_blend(st->cso_context); + cso_save_stencil_ref(st->cso_context); cso_save_depth_stencil_alpha(st->cso_context); cso_save_rasterizer(st->cso_context); cso_save_fragment_shader(st->cso_context); @@ -254,14 +255,17 @@ clear_with_quad(GLcontext *ctx, } if (stencil) { + struct pipe_stencil_ref stencil_ref; + memset(&stencil_ref, 0, sizeof(stencil_ref)); depth_stencil.stencil[0].enabled = 1; depth_stencil.stencil[0].func = PIPE_FUNC_ALWAYS; depth_stencil.stencil[0].fail_op = PIPE_STENCIL_OP_REPLACE; depth_stencil.stencil[0].zpass_op = PIPE_STENCIL_OP_REPLACE; depth_stencil.stencil[0].zfail_op = PIPE_STENCIL_OP_REPLACE; - depth_stencil.stencil[0].ref_value = ctx->Stencil.Clear; depth_stencil.stencil[0].valuemask = 0xff; depth_stencil.stencil[0].writemask = ctx->Stencil.WriteMask[0] & 0xff; + stencil_ref.ref_value[0] = ctx->Stencil.Clear; + cso_set_stencil_ref(st->cso_context, &stencil_ref); } cso_set_depth_stencil_alpha(st->cso_context, &depth_stencil); @@ -277,10 +281,12 @@ clear_with_quad(GLcontext *ctx, /* Restore pipe state */ cso_restore_blend(st->cso_context); + cso_restore_stencil_ref(st->cso_context); cso_restore_depth_stencil_alpha(st->cso_context); cso_restore_rasterizer(st->cso_context); cso_restore_fragment_shader(st->cso_context); cso_restore_vertex_shader(st->cso_context); + } diff --git a/src/mesa/state_tracker/st_cb_drawpixels.c b/src/mesa/state_tracker/st_cb_drawpixels.c index 2a084ca577..36c0a2b0e1 100644 --- a/src/mesa/state_tracker/st_cb_drawpixels.c +++ b/src/mesa/state_tracker/st_cb_drawpixels.c @@ -93,8 +93,9 @@ is_passthrough_program(const struct gl_fragment_program *prog) /** * Make fragment shader for glDraw/CopyPixels. This shader is made * by combining the pixel transfer shader with the user-defined shader. + * \return pointer to Gallium driver fragment shader */ -static struct st_fragment_program * +static void * combined_drawpix_fragment_program(GLcontext *ctx) { struct st_context *st = st_context(ctx); @@ -113,7 +114,7 @@ combined_drawpix_fragment_program(GLcontext *ctx) */ if (is_passthrough_program(&st->fp->Base)) { stfp = (struct st_fragment_program *) - _mesa_clone_program(ctx, &st->pixel_xfer.program->Base.Base); + _mesa_clone_fragment_program(ctx, &st->pixel_xfer.program->Base); } else { #if 0 @@ -156,7 +157,7 @@ combined_drawpix_fragment_program(GLcontext *ctx) */ st_upload_constants(st, stfp->Base.Base.Parameters, PIPE_SHADER_FRAGMENT); - return stfp; + return stfp->driver_shader; } @@ -164,8 +165,9 @@ combined_drawpix_fragment_program(GLcontext *ctx) * Create fragment shader that does a TEX() instruction to get a Z * value, then writes to FRAG_RESULT_DEPTH. * Pass fragment color through as-is. + * \return pointer to the Gallium driver fragment shader */ -static struct st_fragment_program * +static void * make_fragment_shader_z(struct st_context *st) { GLcontext *ctx = st->ctx; @@ -173,7 +175,7 @@ make_fragment_shader_z(struct st_context *st) GLuint ic = 0; if (st->drawpix.z_shader) { - return st->drawpix.z_shader; + return st->drawpix.z_shader->driver_shader; } /* @@ -223,7 +225,7 @@ make_fragment_shader_z(struct st_context *st) st->drawpix.z_shader = (struct st_fragment_program *) p; st_translate_fragment_program(st, st->drawpix.z_shader); - return st->drawpix.z_shader; + return st->drawpix.z_shader->driver_shader; } @@ -233,8 +235,8 @@ make_fragment_shader_z(struct st_context *st) * vertex position and texcoord (and optionally, color). */ static void * -st_make_passthrough_vertex_shader(struct st_context *st, - GLboolean passColor) +make_passthrough_vertex_shader(struct st_context *st, + GLboolean passColor) { if (!st->drawpix.vert_shaders[passColor]) { struct ureg_program *ureg = @@ -270,8 +272,12 @@ st_make_passthrough_vertex_shader(struct st_context *st, } +/** + * Return a texture internalFormat for drawing/copying an image + * of the given type. + */ static GLenum -_mesa_base_format(GLenum format) +base_format(GLenum format) { switch (format) { case GL_DEPTH_COMPONENT: @@ -306,7 +312,7 @@ make_texture(struct st_context *st, GLenum baseFormat; int ptw, pth; - baseFormat = _mesa_base_format(format); + baseFormat = base_format(format); mformat = st_ChooseTextureFormat(ctx, baseFormat, format, type); assert(mformat); @@ -764,10 +770,8 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const struct gl_pixelstore_attrib *unpack, const GLvoid *pixels) { - struct st_fragment_program *stfp; - void *driver_vp; + void *driver_vp, *driver_fp; struct st_context *st = st_context(ctx); - struct pipe_surface *ps; const GLfloat *color; if (format == GL_STENCIL_INDEX || @@ -783,15 +787,13 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, st_validate_state(st); if (format == GL_DEPTH_COMPONENT) { - ps = st->state.framebuffer.zsbuf; - stfp = make_fragment_shader_z(st); - driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE); + driver_fp = make_fragment_shader_z(st); + driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); color = ctx->Current.RasterColor; } else { - ps = st->state.framebuffer.cbufs[0]; - stfp = combined_drawpix_fragment_program(ctx); - driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE); + driver_fp = combined_drawpix_fragment_program(ctx); + driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); color = NULL; } @@ -804,7 +806,7 @@ st_DrawPixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height, width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, pt, driver_vp, - stfp->driver_shader, + driver_fp, color, GL_FALSE); pipe_texture_reference(&pt, NULL); } @@ -922,8 +924,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, struct pipe_context *pipe = st->pipe; struct pipe_screen *screen = pipe->screen; struct st_renderbuffer *rbRead; - void *driver_vp; - struct st_fragment_program *stfp; + void *driver_vp, *driver_fp; struct pipe_texture *pt; GLfloat *color; enum pipe_format srcFormat, texFormat; @@ -970,15 +971,15 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, if (type == GL_COLOR) { rbRead = st_get_color_read_renderbuffer(ctx); color = NULL; - stfp = combined_drawpix_fragment_program(ctx); - driver_vp = st_make_passthrough_vertex_shader(st, GL_FALSE); + driver_fp = combined_drawpix_fragment_program(ctx); + driver_vp = make_passthrough_vertex_shader(st, GL_FALSE); } else { assert(type == GL_DEPTH); rbRead = st_renderbuffer(ctx->ReadBuffer->_DepthBuffer); color = ctx->Current.Attrib[VERT_ATTRIB_COLOR0]; - stfp = make_fragment_shader_z(st); - driver_vp = st_make_passthrough_vertex_shader(st, GL_TRUE); + driver_fp = make_fragment_shader_z(st); + driver_vp = make_passthrough_vertex_shader(st, GL_TRUE); } srcFormat = rbRead->texture->format; @@ -1112,7 +1113,7 @@ st_CopyPixels(GLcontext *ctx, GLint srcx, GLint srcy, width, height, ctx->Pixel.ZoomX, ctx->Pixel.ZoomY, pt, driver_vp, - stfp->driver_shader, + driver_fp, color, GL_TRUE); pipe_texture_reference(&pt, NULL); diff --git a/src/mesa/state_tracker/st_cb_program.c b/src/mesa/state_tracker/st_cb_program.c index 82ef5572e1..2361b2eddf 100644 --- a/src/mesa/state_tracker/st_cb_program.c +++ b/src/mesa/state_tracker/st_cb_program.c @@ -148,9 +148,9 @@ st_delete_program(GLcontext *ctx, struct gl_program *prog) stfp->driver_shader = NULL; } - if (stfp->state.tokens) { - st_free_tokens(stfp->state.tokens); - stfp->state.tokens = NULL; + if (stfp->tgsi.tokens) { + st_free_tokens(stfp->tgsi.tokens); + stfp->tgsi.tokens = NULL; } if (stfp->bitmap_program) { @@ -193,9 +193,9 @@ static GLboolean st_program_string_notify( GLcontext *ctx, stfp->driver_shader = NULL; } - if (stfp->state.tokens) { - st_free_tokens(stfp->state.tokens); - stfp->state.tokens = NULL; + if (stfp->tgsi.tokens) { + st_free_tokens(stfp->tgsi.tokens); + stfp->tgsi.tokens = NULL; } if (st->fp == stfp) diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c index 2281d10e99..dc40c5d269 100644 --- a/src/mesa/state_tracker/st_cb_queryobj.c +++ b/src/mesa/state_tracker/st_cb_queryobj.c @@ -130,13 +130,8 @@ st_CheckQuery(GLcontext *ctx, struct gl_query_object *q) { struct pipe_context *pipe = ctx->st->pipe; struct st_query_object *stq = st_query_object(q); - - if (!q->Ready) { - q->Ready = pipe->get_query_result(pipe, - stq->pq, - FALSE, - &q->Result); - } + assert(!q->Ready); /* we should not get called if Ready is TRUE */ + q->Ready = pipe->get_query_result(pipe, stq->pq, FALSE, &q->Result); } diff --git a/src/mesa/state_tracker/st_cb_rasterpos.c b/src/mesa/state_tracker/st_cb_rasterpos.c index 42a1377809..4692891c8a 100644 --- a/src/mesa/state_tracker/st_cb_rasterpos.c +++ b/src/mesa/state_tracker/st_cb_rasterpos.c @@ -251,6 +251,14 @@ st_RasterPos(GLcontext *ctx, const GLfloat v[4]) /* draw the point */ st_feedback_draw_vbo(ctx, rs->arrays, &rs->prim, 1, NULL, GL_TRUE, 0, 1); + + /* restore draw's rasterization stage depending on rendermode */ + if (ctx->RenderMode == GL_FEEDBACK) { + draw_set_rasterize_stage(draw, st->feedback_stage); + } + else if (ctx->RenderMode == GL_SELECT) { + draw_set_rasterize_stage(draw, st->selection_stage); + } } diff --git a/src/mesa/state_tracker/st_cb_viewport.h b/src/mesa/state_tracker/st_cb_viewport.h deleted file mode 100644 index 44948e5316..0000000000 --- a/src/mesa/state_tracker/st_cb_viewport.h +++ /dev/null @@ -1,29 +0,0 @@ -/************************************************************************** - * - * Copyright 2009 VMware, Inc. - * All Rights Reserved. - * - * Permission is hereby granted, free of charge, to any person obtaining a - * copy of this software and associated documentation files (the - * "Software"), to deal in the Software without restriction, including - * without limitation the rights to use, copy, modify, merge, publish, - * distribute, 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 TUNGSTEN GRAPHICS AND/OR ITS 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. - * - **************************************************************************/ - -extern void -st_init_viewport_functions(struct dd_function_table *functions); diff --git a/src/mesa/state_tracker/st_context.c b/src/mesa/state_tracker/st_context.c index 8f6a0c2423..5b3987d73a 100644 --- a/src/mesa/state_tracker/st_context.c +++ b/src/mesa/state_tracker/st_context.c @@ -56,7 +56,6 @@ #include "st_cb_texture.h" #include "st_cb_flush.h" #include "st_cb_strings.h" -#include "st_cb_viewport.h" #include "st_atom.h" #include "st_draw.h" #include "st_extensions.h" @@ -343,7 +342,6 @@ void st_init_driver_functions(struct dd_function_table *functions) st_init_texture_functions(functions); st_init_flush_functions(functions); st_init_string_functions(functions); - st_init_viewport_functions(functions); functions->UpdateState = st_invalidate_state; } diff --git a/src/mesa/state_tracker/st_debug.c b/src/mesa/state_tracker/st_debug.c index 6e699ca552..5dbabfa5c2 100644 --- a/src/mesa/state_tracker/st_debug.c +++ b/src/mesa/state_tracker/st_debug.c @@ -87,11 +87,11 @@ st_print_current(void) #endif if (st->vp->varients) - tgsi_dump( st->vp->varients[0].state.tokens, 0 ); + tgsi_dump( st->vp->varients[0].tgsi.tokens, 0 ); if (st->vp->Base.Base.Parameters) _mesa_print_parameter_list(st->vp->Base.Base.Parameters); - tgsi_dump( st->fp->state.tokens, 0 ); + tgsi_dump( st->fp->tgsi.tokens, 0 ); if (st->fp->Base.Base.Parameters) _mesa_print_parameter_list(st->fp->Base.Base.Parameters); } diff --git a/src/mesa/state_tracker/st_draw.c b/src/mesa/state_tracker/st_draw.c index e1dcb154c1..4b48c168e9 100644 --- a/src/mesa/state_tracker/st_draw.c +++ b/src/mesa/state_tracker/st_draw.c @@ -56,6 +56,7 @@ #include "pipe/p_context.h" #include "pipe/p_defines.h" #include "util/u_inlines.h" +#include "util/u_format.h" static GLuint double_types[4] = { @@ -596,7 +597,7 @@ st_draw_vbo(GLcontext *ctx, printf("vlements[%d].vbuffer_index = %u\n", i, velements[i].vertex_buffer_index); printf("vlements[%d].src_offset = %u\n", i, velements[i].src_offset); printf("vlements[%d].nr_comps = %u\n", i, velements[i].nr_components); - printf("vlements[%d].format = %s\n", i, pf_name(velements[i].src_format)); + printf("vlements[%d].format = %s\n", i, util_format_name(velements[i].src_format)); } } #endif @@ -645,20 +646,18 @@ st_draw_vbo(GLcontext *ctx, } /* draw */ - if (nr_prims == 1 && pipe->draw_range_elements != NULL) { - i = 0; - + if (pipe->draw_range_elements && min_index != ~0 && max_index != ~0) { /* XXX: exercise temporary path to pass min/max directly * through to driver & draw module. These interfaces still * need a bit of work... */ - prim = translate_prim( ctx, prims[i].mode ); + for (i = 0; i < nr_prims; i++) { + prim = translate_prim( ctx, prims[i].mode ); - pipe->draw_range_elements(pipe, indexBuf, indexSize, - min_index, - max_index, - prim, - prims[i].start + indexOffset, prims[i].count); + pipe->draw_range_elements(pipe, indexBuf, indexSize, + min_index, max_index, prim, + prims[i].start + indexOffset, prims[i].count); + } } else { for (i = 0; i < nr_prims; i++) { diff --git a/src/mesa/state_tracker/st_draw_feedback.c b/src/mesa/state_tracker/st_draw_feedback.c index 75ad1a97cf..087f2f22bb 100644 --- a/src/mesa/state_tracker/st_draw_feedback.c +++ b/src/mesa/state_tracker/st_draw_feedback.c @@ -119,7 +119,7 @@ st_feedback_draw_vbo(GLcontext *ctx, /* must get these after state validation! */ vp = ctx->st->vp; - vs = &st->vp_varient->state; + vs = &st->vp_varient->tgsi; if (!st->vp_varient->draw_shader) { st->vp_varient->draw_shader = draw_create_vertex_shader(draw, vs); diff --git a/src/mesa/state_tracker/st_format.c b/src/mesa/state_tracker/st_format.c index 3ffc2aee2a..851c16f83c 100644 --- a/src/mesa/state_tracker/st_format.c +++ b/src/mesa/state_tracker/st_format.c @@ -85,7 +85,7 @@ st_get_format_info(enum pipe_format format, struct pipe_format_info *pinfo) if (desc->layout == UTIL_FORMAT_LAYOUT_ARITH || desc->layout == UTIL_FORMAT_LAYOUT_ARRAY) { #if 0 - printf("%s\n", pf_name( format ) ); + printf("%s\n", util_format_name( format ) ); #endif /* Data type */ diff --git a/src/mesa/state_tracker/st_program.c b/src/mesa/state_tracker/st_program.c index 21ad6fef2b..7ce3938904 100644 --- a/src/mesa/state_tracker/st_program.c +++ b/src/mesa/state_tracker/st_program.c @@ -68,8 +68,8 @@ st_vp_release_varients( struct st_context *st, if (vpv->draw_shader) draw_delete_vertex_shader( st->draw, vpv->draw_shader ); - if (vpv->state.tokens) - st_free_tokens(vpv->state.tokens); + if (vpv->tgsi.tokens) + st_free_tokens(vpv->tgsi.tokens); FREE( vpv ); @@ -236,13 +236,13 @@ st_translate_vertex_program(struct st_context *st, if (error) goto fail; - vpv->state.tokens = ureg_get_tokens( ureg, NULL ); - if (!vpv->state.tokens) + vpv->tgsi.tokens = ureg_get_tokens( ureg, NULL ); + if (!vpv->tgsi.tokens) goto fail; ureg_destroy( ureg ); - vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->state); + vpv->driver_shader = pipe->create_vs_state(pipe, &vpv->tgsi); if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) { _mesa_print_program(&stvp->Base.Base); @@ -250,7 +250,7 @@ st_translate_vertex_program(struct st_context *st, } if (ST_DEBUG & DEBUG_TGSI) { - tgsi_dump( vpv->state.tokens, 0 ); + tgsi_dump( vpv->tgsi.tokens, 0 ); debug_printf("\n"); } @@ -278,12 +278,14 @@ st_translate_fragment_program(struct st_context *st, struct pipe_context *pipe = st->pipe; GLuint outputMapping[FRAG_RESULT_MAX]; GLuint inputMapping[FRAG_ATTRIB_MAX]; - GLuint interpMode[16]; /* XXX size? */ + GLuint interpMode[PIPE_MAX_SHADER_INPUTS]; /* XXX size? */ GLuint attr; enum pipe_error error; const GLbitfield inputsRead = stfp->Base.Base.InputsRead; struct ureg_program *ureg; + ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; + ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; uint fs_num_inputs = 0; ubyte fs_output_semantic_name[PIPE_MAX_SHADER_OUTPUTS]; @@ -301,28 +303,28 @@ st_translate_fragment_program(struct st_context *st, switch (attr) { case FRAG_ATTRIB_WPOS: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; - stfp->input_semantic_index[slot] = 0; + input_semantic_name[slot] = TGSI_SEMANTIC_POSITION; + input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_LINEAR; break; case FRAG_ATTRIB_COL0: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - stfp->input_semantic_index[slot] = 0; + input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_LINEAR; break; case FRAG_ATTRIB_COL1: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; - stfp->input_semantic_index[slot] = 1; + input_semantic_name[slot] = TGSI_SEMANTIC_COLOR; + input_semantic_index[slot] = 1; interpMode[slot] = TGSI_INTERPOLATE_LINEAR; break; case FRAG_ATTRIB_FOGC: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FOG; - stfp->input_semantic_index[slot] = 0; + input_semantic_name[slot] = TGSI_SEMANTIC_FOG; + input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; break; case FRAG_ATTRIB_FACE: - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_FACE; - stfp->input_semantic_index[slot] = 0; + input_semantic_name[slot] = TGSI_SEMANTIC_FACE; + input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_CONSTANT; break; case FRAG_ATTRIB_PNTC: @@ -331,8 +333,8 @@ st_translate_fragment_program(struct st_context *st, * shader input is the point coord attribute so that it can set * up the right vertex attribute values. */ - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; - stfp->input_semantic_index[slot] = 0; + input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + input_semantic_index[slot] = 0; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; break; @@ -365,8 +367,8 @@ st_translate_fragment_program(struct st_context *st, * readability of the generated TGSI. */ assert(attr >= FRAG_ATTRIB_TEX0); - stfp->input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0); - stfp->input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; + input_semantic_index[slot] = (attr - FRAG_ATTRIB_TEX0); + input_semantic_name[slot] = TGSI_SEMANTIC_GENERIC; interpMode[slot] = TGSI_INTERPOLATE_PERSPECTIVE; break; } @@ -428,8 +430,8 @@ st_translate_fragment_program(struct st_context *st, /* inputs */ fs_num_inputs, inputMapping, - stfp->input_semantic_name, - stfp->input_semantic_index, + input_semantic_name, + input_semantic_index, interpMode, /* outputs */ fs_num_outputs, @@ -437,9 +439,9 @@ st_translate_fragment_program(struct st_context *st, fs_output_semantic_name, fs_output_semantic_index, FALSE ); - stfp->state.tokens = ureg_get_tokens( ureg, NULL ); + stfp->tgsi.tokens = ureg_get_tokens( ureg, NULL ); ureg_destroy( ureg ); - stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->state); + stfp->driver_shader = pipe->create_fs_state(pipe, &stfp->tgsi); if ((ST_DEBUG & DEBUG_TGSI) && (ST_DEBUG & DEBUG_MESA)) { _mesa_print_program(&stfp->Base.Base); @@ -447,7 +449,7 @@ st_translate_fragment_program(struct st_context *st, } if (ST_DEBUG & DEBUG_TGSI) { - tgsi_dump( stfp->state.tokens, 0/*TGSI_DUMP_VERBOSE*/ ); + tgsi_dump( stfp->tgsi.tokens, 0/*TGSI_DUMP_VERBOSE*/ ); debug_printf("\n"); } } diff --git a/src/mesa/state_tracker/st_program.h b/src/mesa/state_tracker/st_program.h index d9822e50f5..1b3f75ca27 100644 --- a/src/mesa/state_tracker/st_program.h +++ b/src/mesa/state_tracker/st_program.h @@ -52,10 +52,7 @@ struct st_fragment_program struct gl_fragment_program Base; GLuint serialNo; - ubyte input_semantic_name[PIPE_MAX_SHADER_INPUTS]; - ubyte input_semantic_index[PIPE_MAX_SHADER_INPUTS]; - - struct pipe_shader_state state; + struct pipe_shader_state tgsi; void *driver_shader; /** Program prefixed with glBitmap prologue */ @@ -82,9 +79,11 @@ struct st_vp_varient */ struct st_vp_varient_key key; - /** TGSI tokens -- why? + /** + * TGSI tokens (to later generate a 'draw' module shader for + * selection/feedback/rasterpos) */ - struct pipe_shader_state state; + struct pipe_shader_state tgsi; /** Driver's compiled shader */ void *driver_shader; diff --git a/src/mesa/swrast/s_aatritemp.h b/src/mesa/swrast/s_aatritemp.h index a8b22c548f..76d4005b8c 100644 --- a/src/mesa/swrast/s_aatritemp.h +++ b/src/mesa/swrast/s_aatritemp.h @@ -328,11 +328,11 @@ #if defined(DO_ATTRIBS) /* compute attributes at left-most fragment */ - span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5, iy + 0.5F, wPlane); + span.attrStart[FRAG_ATTRIB_WPOS][3] = solve_plane(ix + 1.5F, iy + 0.5F, wPlane); ATTRIB_LOOP_BEGIN GLuint c; for (c = 0; c < 4; c++) { - span.attrStart[attr][c] = solve_plane(ix + 1.5, iy + 0.5F, attrPlane[attr][c]); + span.attrStart[attr][c] = solve_plane(ix + 1.5F, iy + 0.5F, attrPlane[attr][c]); } ATTRIB_LOOP_END #endif diff --git a/src/mesa/swrast/s_atifragshader.c b/src/mesa/swrast/s_atifragshader.c index 05da64de3a..0f06cdf9f9 100644 --- a/src/mesa/swrast/s_atifragshader.c +++ b/src/mesa/swrast/s_atifragshader.c @@ -86,7 +86,7 @@ apply_swizzle(GLfloat values[4], GLuint swizzle) q = 0.000000001F; values[0] = s / q; values[1] = t / q; - values[2] = 1.0 / q; + values[2] = 1.0F / q; break; } values[3] = 0.0; @@ -138,7 +138,7 @@ apply_src_mod(GLint optype, GLuint mod, GLfloat * val) val[i] = 1 - val[i]; if (mod & GL_BIAS_BIT_ATI) - val[i] = val[i] - 0.5; + val[i] = val[i] - 0.5F; if (mod & GL_2X_BIT_ATI) val[i] = 2 * val[i]; diff --git a/src/mesa/swrast/s_clear.c b/src/mesa/swrast/s_clear.c index 21167a64b3..820297f3ee 100644 --- a/src/mesa/swrast/s_clear.c +++ b/src/mesa/swrast/s_clear.c @@ -77,7 +77,7 @@ clear_rgba_buffer_with_masking(GLcontext *ctx, struct gl_renderbuffer *rb, UNCLAMPED_FLOAT_TO_USHORT(clearColor[BCOMP], ctx->Color.ClearColor[2]); UNCLAMPED_FLOAT_TO_USHORT(clearColor[ACOMP], ctx->Color.ClearColor[3]); for (i = 0; i < width; i++) { - COPY_4V(span.array->rgba[i], clearColor); + COPY_4V_CAST(span.array->rgba[i], clearColor, GLchan); } } else { diff --git a/src/mesa/swrast/s_texcombine.c b/src/mesa/swrast/s_texcombine.c index 95e2c082ba..f322663ad4 100644 --- a/src/mesa/swrast/s_texcombine.c +++ b/src/mesa/swrast/s_texcombine.c @@ -368,7 +368,7 @@ texture_combine( GLcontext *ctx, GLuint unit, GLuint n, (arg0[i][GCOMP] - 0.5F) * (arg1[i][GCOMP] - 0.5F) + (arg0[i][BCOMP] - 0.5F) * (arg1[i][BCOMP] - 0.5F)) * 4.0F * scaleRGB; - dot = CLAMP(dot, 0.0, 1.0F); + dot = CLAMP(dot, 0.0F, 1.0F); rgba[i][RCOMP] = rgba[i][GCOMP] = rgba[i][BCOMP] = dot; } break; diff --git a/src/mesa/swrast_setup/ss_context.c b/src/mesa/swrast_setup/ss_context.c index 61172f9979..23d3cb3807 100644 --- a/src/mesa/swrast_setup/ss_context.c +++ b/src/mesa/swrast_setup/ss_context.c @@ -122,7 +122,7 @@ setup_vertex_format(GLcontext *ctx) swsetup->last_index_bitset)) { DECLARE_RENDERINPUTS(index_bitset); struct tnl_attr_map map[_TNL_ATTRIB_MAX]; - int i, e = 0; + unsigned int i, e = 0; swsetup->intColors = intColors; diff --git a/src/mesa/swrast_setup/ss_tritmp.h b/src/mesa/swrast_setup/ss_tritmp.h index d9bf54dd46..b9b78e16b0 100644 --- a/src/mesa/swrast_setup/ss_tritmp.h +++ b/src/mesa/swrast_setup/ss_tritmp.h @@ -132,9 +132,9 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) saved_index[1] = v[1]->attrib[FRAG_ATTRIB_CI][0]; saved_index[2] = v[2]->attrib[FRAG_ATTRIB_CI][0]; - SS_IND(v[0]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e0]); - SS_IND(v[1]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e1]); - SS_IND(v[2]->attrib[FRAG_ATTRIB_CI][0], (GLuint) vbindex[e2]); + SS_IND(v[0]->attrib[FRAG_ATTRIB_CI][0], vbindex[e0]); + SS_IND(v[1]->attrib[FRAG_ATTRIB_CI][0], vbindex[e1]); + SS_IND(v[2]->attrib[FRAG_ATTRIB_CI][0], vbindex[e2]); } } } @@ -159,9 +159,9 @@ static void TAG(triangle)(GLcontext *ctx, GLuint e0, GLuint e1, GLuint e2 ) offset += MAX2(dzdx, dzdy) * ctx->Polygon.OffsetFactor; } /* new Z values */ - oz0 = CLAMP(v[0]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max); - oz1 = CLAMP(v[1]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max); - oz2 = CLAMP(v[2]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0, max); + oz0 = CLAMP(v[0]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0F, max); + oz1 = CLAMP(v[1]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0F, max); + oz2 = CLAMP(v[2]->attrib[FRAG_ATTRIB_WPOS][2] + offset, 0.0F, max); } } diff --git a/src/mesa/tnl/t_draw.c b/src/mesa/tnl/t_draw.c index 812d712b07..149f693711 100644 --- a/src/mesa/tnl/t_draw.c +++ b/src/mesa/tnl/t_draw.c @@ -429,7 +429,7 @@ void _tnl_draw_prims( GLcontext *ctx, _tnl_vbo_draw_prims ); return; } - else if (max_index + max_basevertex > max) { + else if ((GLint)max_index + max_basevertex > max) { /* The software TNL pipeline has a fixed amount of storage for * vertices and it is necessary to split incoming drawing commands * if they exceed that limit. diff --git a/src/mesa/vbo/vbo_exec_array.c b/src/mesa/vbo/vbo_exec_array.c index 88502f3d35..a284e4047f 100644 --- a/src/mesa/vbo/vbo_exec_array.c +++ b/src/mesa/vbo/vbo_exec_array.c @@ -935,13 +935,13 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode, vbo->draw_prims(ctx, exec->array.inputs, prim, primcount, &ib, GL_FALSE, ~0, ~0); } else { + /* render one prim at a time */ for (i = 0; i < primcount; i++) { ib.count = count[i]; ib.type = type; ib.obj = ctx->Array.ElementArrayBufferObj; ib.ptr = indices[i]; - prim[0].begin = 1; prim[0].end = 1; prim[0].weak = 0; @@ -954,11 +954,12 @@ vbo_validated_multidrawelements(GLcontext *ctx, GLenum mode, prim[0].basevertex = basevertex[i]; else prim[0].basevertex = 0; - } - vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib, - GL_FALSE, ~0, ~0); + vbo->draw_prims(ctx, exec->array.inputs, prim, 1, &ib, + GL_FALSE, ~0, ~0); + } } + _mesa_free(prim); } |