Merge branch 'gallium-front-ccw'
authorKeith Whitwell <keithw@vmware.com>
Fri, 21 May 2010 14:41:06 +0000 (15:41 +0100)
committerKeith Whitwell <keithw@vmware.com>
Fri, 21 May 2010 14:41:06 +0000 (15:41 +0100)
156 files changed:
SConstruct
common.py
configure.ac
include/EGL/eglext.h
progs/egl/opengl/Makefile
progs/egl/opengl/eglgears.c
progs/egl/opengles1/Makefile
progs/egl/opengles1/pbuffer.c
progs/egl/opengles1/render_tex.c
progs/egl/opengles1/torus.c
progs/egl/opengles2/Makefile
progs/egl/opengles2/es2gears.c
progs/egl/opengles2/tri.c
progs/egl/openvg/Makefile
progs/vpglsl/func.glsl [new file with mode: 0644]
progs/vpglsl/func2.glsl [new file with mode: 0644]
progs/xdemos/glxinfo.c
src/egl/drivers/Makefile.template
src/egl/drivers/dri2/egl_dri2.c
src/egl/drivers/glx/egl_glx.c
src/egl/main/eglapi.c
src/egl/main/eglconfig.c
src/egl/main/eglconfig.h
src/egl/main/egldisplay.h
src/egl/main/eglmisc.c
src/egl/main/eglsurface.c
src/egl/main/eglsurface.h
src/gallium/SConscript
src/gallium/auxiliary/draw/draw_llvm.c
src/gallium/auxiliary/gallivm/lp_bld_debug.h
src/gallium/auxiliary/gallivm/lp_bld_flow.c
src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
src/gallium/auxiliary/gallivm/lp_bld_init.c
src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
src/gallium/auxiliary/gallivm/lp_bld_type.c
src/gallium/auxiliary/gallivm/lp_bld_type.h
src/gallium/auxiliary/tgsi/tgsi_exec.c
src/gallium/auxiliary/tgsi/tgsi_ppc.c
src/gallium/auxiliary/util/u_debug_symbol.c
src/gallium/auxiliary/util/u_dump.h
src/gallium/auxiliary/util/u_dump_defines.c
src/gallium/auxiliary/util/u_format_pack.py
src/gallium/auxiliary/util/u_format_parse.py
src/gallium/auxiliary/util/u_format_srgb.py
src/gallium/auxiliary/util/u_half.py
src/gallium/docs/source/context.rst
src/gallium/docs/source/screen.rst
src/gallium/drivers/cell/ppu/cell_screen.c
src/gallium/drivers/i915/i915_screen.c
src/gallium/drivers/i965/brw_batchbuffer.c
src/gallium/drivers/i965/brw_resource_texture.c
src/gallium/drivers/i965/brw_screen.c
src/gallium/drivers/llvmpipe/Makefile
src/gallium/drivers/llvmpipe/lp_debug.h
src/gallium/drivers/llvmpipe/lp_jit.c
src/gallium/drivers/llvmpipe/lp_screen.c
src/gallium/drivers/llvmpipe/lp_state_fs.c
src/gallium/drivers/nv50/nv50_program.c
src/gallium/drivers/nv50/nv50_push.c
src/gallium/drivers/nv50/nv50_screen.c
src/gallium/drivers/nv50/nv50_transfer.c
src/gallium/drivers/nvfx/nvfx_screen.c
src/gallium/drivers/r300/r300_context.c
src/gallium/drivers/r300/r300_context.h
src/gallium/drivers/r300/r300_debug.c
src/gallium/drivers/r300/r300_emit.c
src/gallium/drivers/r300/r300_flush.c
src/gallium/drivers/r300/r300_query.c
src/gallium/drivers/r300/r300_render.c
src/gallium/drivers/r300/r300_screen.c
src/gallium/drivers/r300/r300_screen.h
src/gallium/drivers/r300/r300_state.c
src/gallium/drivers/r300/r300_state_derived.c
src/gallium/drivers/r300/r300_vs.c
src/gallium/drivers/r300/r300_vs.h
src/gallium/drivers/r300/r300_winsys.h
src/gallium/drivers/rbug/rbug_screen.c
src/gallium/drivers/softpipe/sp_query.c
src/gallium/drivers/softpipe/sp_screen.c
src/gallium/drivers/softpipe/sp_texture.c
src/gallium/drivers/svga/svga_screen.c
src/gallium/drivers/svga/svga_swtnl.h
src/gallium/drivers/trace/tr_dump.h
src/gallium/include/pipe/p_defines.h
src/gallium/include/pipe/p_screen.h
src/gallium/include/state_tracker/dri1_api.h
src/gallium/include/state_tracker/drm_api.h
src/gallium/include/state_tracker/graw.h
src/gallium/state_trackers/glx/xlib/glx_getproc.c
src/gallium/state_trackers/xorg/xorg_crtc.c
src/gallium/state_trackers/xorg/xorg_dri2.c
src/gallium/state_trackers/xorg/xorg_driver.c
src/gallium/state_trackers/xorg/xorg_exa.c
src/gallium/state_trackers/xorg/xorg_output.c
src/gallium/state_trackers/xorg/xorg_renderer.c
src/gallium/state_trackers/xorg/xorg_tracker.h
src/gallium/targets/Makefile.egl
src/gallium/targets/SConscript
src/gallium/targets/graw-null/graw_null.c
src/gallium/targets/graw-xlib/SConscript
src/gallium/targets/graw-xlib/graw_util.c [new file with mode: 0644]
src/gallium/targets/graw-xlib/graw_xlib.c
src/gallium/tests/graw/SConscript
src/gallium/tests/graw/clear.c
src/gallium/tests/graw/quad-tex.c [new file with mode: 0644]
src/gallium/winsys/radeon/drm/radeon_buffer.h
src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
src/gallium/winsys/radeon/drm/radeon_r300.c
src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
src/glx/dri2_glx.c
src/mapi/es1api/Makefile
src/mesa/drivers/dri/i965/brw_clip.c
src/mesa/drivers/dri/i965/brw_clip.h
src/mesa/drivers/dri/i965/brw_clip_tri.c
src/mesa/drivers/dri/i965/brw_clip_util.c
src/mesa/drivers/dri/i965/brw_context.c
src/mesa/drivers/dri/i965/brw_context.h
src/mesa/drivers/dri/i965/brw_defines.h
src/mesa/drivers/dri/i965/brw_disasm.c
src/mesa/drivers/dri/i965/brw_draw_upload.c
src/mesa/drivers/dri/i965/brw_eu.h
src/mesa/drivers/dri/i965/brw_eu_emit.c
src/mesa/drivers/dri/i965/brw_gs.c
src/mesa/drivers/dri/i965/brw_gs_emit.c
src/mesa/drivers/dri/i965/brw_queryobj.c
src/mesa/drivers/dri/i965/brw_sf.c
src/mesa/drivers/dri/i965/brw_vs.c
src/mesa/drivers/dri/i965/brw_vs.h
src/mesa/drivers/dri/i965/brw_vs_emit.c
src/mesa/drivers/dri/i965/brw_wm_emit.c
src/mesa/drivers/dri/i965/brw_wm_glsl.c
src/mesa/drivers/dri/intel/intel_batchbuffer.c
src/mesa/drivers/dri/intel/intel_blit.c
src/mesa/drivers/dri/intel/intel_context.c
src/mesa/drivers/dri/intel/intel_context.h
src/mesa/drivers/dri/intel/intel_screen.c
src/mesa/drivers/dri/intel/intel_tex_format.c
src/mesa/drivers/dri/r300/compiler/Makefile
src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
src/mesa/drivers/dri/r300/compiler/radeon_optimize.c [new file with mode: 0644]
src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
src/mesa/main/dlopen.c
src/mesa/main/drawtex.c
src/mesa/main/get.c
src/mesa/main/querymatrix.c
src/mesa/main/transformfeedback.c
src/mesa/shader/shader_api.c
src/mesa/state_tracker/st_cb_queryobj.c
src/mesa/state_tracker/st_cb_readpixels.c
src/mesa/state_tracker/st_extensions.c

index 28ed6ea78c0db95d1ed09cde3a1e47331b8c3d63..c843b41b0dc933c6f7562a13108d29933a053612 100644 (file)
@@ -31,6 +31,7 @@ import common
 # Configuration options
 
 default_statetrackers = 'mesa'
+default_targets = 'none'
 
 if common.default_platform in ('linux', 'freebsd', 'darwin'):
        default_drivers = 'softpipe,failover,svga,i915,i965,trace,identity,llvmpipe'
@@ -54,6 +55,28 @@ opts.Add(ListVariable('drivers', 'pipe drivers to build', default_drivers,
 opts.Add(ListVariable('winsys', 'winsys drivers to build', default_winsys,
                      ['xlib', 'vmware', 'i915', 'i965', 'gdi', 'radeon', 'graw-xlib']))
 
+opts.Add(ListVariable('targets', 'driver targets to build', default_targets,
+                     ['dri-i915',
+                      'dri-i965',
+                      'dri-nouveau',
+                      'dri-radeong',
+                      'dri-swrast',
+                      'dri-vmwgfx',
+                      'egl-i915',
+                      'egl-i965',
+                      'egl-nouveau',
+                      'egl-radeon',
+                      'egl-swrast',
+                      'egl-vmwgfx',
+                      'graw-xlib',
+                      'libgl-gdi',
+                      'libgl-xlib',
+                      'xorg-i915',
+                      'xorg-i965',
+                      'xorg-nouveau',
+                      'xorg-radeon',
+                      'xorg-vmwgfx']))
+
 opts.Add(EnumVariable('MSVS_VERSION', 'MS Visual C++ version', None, allowed_values=('7.1', '8.0', '9.0')))
 
 env = Environment(
index 742dabf4c45d38d269b5935375297c314436f14d..bdca375f8b0d3f0633638648daf10150c07c0664 100644 (file)
--- a/common.py
+++ b/common.py
@@ -3,6 +3,7 @@
 
 import os
 import os.path
+import re
 import subprocess
 import sys
 import platform as _platform
@@ -28,22 +29,38 @@ _machine_map = {
        'ppc' : 'ppc',
        'x86_64': 'x86_64',
 }
+
+
+# find default_machine value
 if 'PROCESSOR_ARCHITECTURE' in os.environ:
        default_machine = os.environ['PROCESSOR_ARCHITECTURE']
 else:
        default_machine = _platform.machine()
 default_machine = _machine_map.get(default_machine, 'generic')
 
+
+# find default_llvm value
 if 'LLVM' in os.environ:
     default_llvm = 'yes'
 else:
+    # Search sys.argv[] for a "platform=foo" argument since we don't have
+    # an 'env' variable at this point.
+    platform = default_platform
+    pattern = re.compile("(platform=)(.*)")
+    for arg in sys.argv:
+        m = pattern.match(arg)
+        if m:
+            platform = m.group(2)
+
     default_llvm = 'no'
     try:
-        if subprocess.call(['llvm-config', '--version'], stdout=subprocess.PIPE) == 0:
+        if platform != 'windows' and subprocess.call(['llvm-config', '--version'], stdout=subprocess.PIPE) == 0:
             default_llvm = 'yes'
     except:
         pass
 
+
+# find default_dri value
 if default_platform in ('linux', 'freebsd'):
        default_dri = 'yes'
 elif default_platform in ('winddk', 'windows', 'wince', 'darwin'):
index 7f6f8db2463ce72b4c856d10af6b4927e04d9abe..eb3460e9eb6c157b6de97146181166c16f3e78ac 100644 (file)
@@ -265,7 +265,7 @@ else
     darwin* )
         LIB_EXTENSION='dylib' ;;
     cygwin* )
-        LIB_EXTENSION='dll' ;;
+        LIB_EXTENSION='dll.a' ;;
     aix* )
         LIB_EXTENSION='a' ;;
     * )
index 61626d20df6f61ce3584d99b5538c3b104cfda1d..e9f5a49b488cbfc566120bbca9d5b19615189290 100644 (file)
@@ -239,6 +239,13 @@ typedef EGLBoolean (EGLAPIENTRYP PFNEGLSWAPBUFFERSREGIONNOK) (EGLDisplay dpy, EG
 #endif
 
 
+#ifndef EGL_NOK_texture_from_pixmap
+#define EGL_NOK_texture_from_pixmap 1
+
+#define EGL_Y_INVERTED_NOK                     0x307F
+#endif /* EGL_NOK_texture_from_pixmap */
+
+
 #ifdef __cplusplus
 }
 #endif
index 79cd5fc65339e8910a5675a076d31df5dfbb0809..a49255bbb2eb57476a7aeae572542898d1752083 100644 (file)
@@ -7,9 +7,9 @@ include $(TOP)/configs/current
 INCLUDE_DIRS = -I$(TOP)/include $(X11_CFLAGS)
 
 HEADERS = $(TOP)/include/GLES/egl.h
-LIB_DEP = $(TOP)/$(LIB_DIR)/libEGL.so
+LIB_DEP = $(TOP)/$(LIB_DIR)/$(EGL_LIB_NAME)
 
-LIBS = -L$(TOP)/$(LIB_DIR) -lEGL -lGL -lm
+LIBS = -L$(TOP)/$(LIB_DIR) -l$(EGL_LIB) -l$(GL_LIB) -lm
 
 EGLUT_DIR = $(TOP)/progs/egl/eglut
 
index 28da9c0ac740c9f86ca5bfc6617d8d83a2e9c933..430deb26e5e1a9b5e3d4268ed11801ee1062f73e 100644 (file)
 
 #include "eglut.h"
 
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
 static GLfloat view_rotx = 20.0, view_roty = 30.0, view_rotz = 0.0;
 static GLint gear1, gear2, gear3;
 static GLfloat angle = 0.0;
index 593145d4bf2a8931b4d8761781ad487ab32026ba..e7802f80034134159da82cac8ec424fd9ee2db63 100644 (file)
@@ -12,13 +12,13 @@ HEADERS = $(TOP)/include/GLES/egl.h
 
 
 ES1_LIB_DEPS = \
-       $(TOP)/$(LIB_DIR)/libEGL.so \
-       $(TOP)/$(LIB_DIR)/libGLESv1_CM.so
+       $(TOP)/$(LIB_DIR)/$(EGL_LIB_NAME) \
+       $(TOP)/$(LIB_DIR)/$(GLESv1_CM_LIB_NAME)
 
 
 ES1_LIBS = \
-       -L$(TOP)/$(LIB_DIR) -lEGL \
-       -L$(TOP)/$(LIB_DIR) -lGLESv1_CM $(LIBDRM_LIB) $(X11_LIBS)
+       -L$(TOP)/$(LIB_DIR) -l$(EGL_LIB) -l$(GLESv1_CM_LIB) \
+       $(LIBDRM_LIB) $(X11_LIBS)
 
 EGLUT_DIR = $(TOP)/progs/egl/eglut
 
index 60f864445af233467bc085505ef6cc7e4625510f..1b4dbb666f4cc08786da8715b87ccf3bb61d9d8a 100644 (file)
@@ -22,6 +22,9 @@
 #include <EGL/egl.h>
 
 
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
 
 static int WinWidth = 300, WinHeight = 300;
 
index 0200fa4cb06c07f7add81e9959855ecc8af962b6..cd2abbd51b7a9334b22415791dfe19ba674d7a00 100644 (file)
 #include <EGL/egl.h>
 
 
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
 static int TexWidth = 256, TexHeight = 256;
 
 static int WinWidth = 300, WinHeight = 300;
index 8f262b53d6c708f5a09a55e82cf2ac9d02beee62..18ddff3fe4ac3f77ff269ca7b2b85d1bb923abd2 100644 (file)
 
 #include "eglut.h"
 
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
 static const struct {
    GLenum internalFormat;
    const char *name;
index 89feb34acc1d90796c909710a1dff7cd7dbcb7b4..bf14513d7fb3880df869f781e26f21dce6dbfbc0 100644 (file)
@@ -14,13 +14,13 @@ HEADERS = $(TOP)/include/GLES/egl.h
 
 
 ES2_LIB_DEPS = \
-       $(TOP)/$(LIB_DIR)/libEGL.so \
-       $(TOP)/$(LIB_DIR)/libGLESv2.so
+       $(TOP)/$(LIB_DIR)/$(EGL_LIB_NAME) \
+       $(TOP)/$(LIB_DIR)/$(GLESv2_LIB_NAME)
 
 
 ES2_LIBS = \
-       -L$(TOP)/$(LIB_DIR) -lEGL \
-       -L$(TOP)/$(LIB_DIR) -lGLESv2 $(LIBDRM_LIB) $(X11_LIBS) \
+       -L$(TOP)/$(LIB_DIR) -l$(EGL_LIB) -l$(GLESv2_LIB) \
+       $(LIBDRM_LIB) $(X11_LIBS)
 
 PROGRAMS = \
        es2_info \
index 8e7a3e52490fe431a8ef214cfea6703660dcfb8c..6bd6594320ac34c363f6892778d7729e3f98e1c7 100644 (file)
 #include <EGL/eglext.h>
 #include "eglut.h"
 
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
 struct gear {
    GLfloat *vertices;
    GLuint vbo;
index 8981d8a7e217e9a5e8507b503fba8da39dc934d6..812dbf031e4b55b8613f8cf5f5b594b663c0ed2c 100644 (file)
 #include <EGL/egl.h>
 
 
+#ifndef M_PI
+#define M_PI 3.14159265
+#endif
+
 #define FLOAT_TO_FIXED(X)   ((X) * 65535.0)
 
 
index 3b11933db26ff6e02ae232ee02393859d53ec9a7..9a96ccc45f7db0163e482cc18215a4b75e906ce1 100644 (file)
@@ -3,7 +3,7 @@
 TOP = ../../..
 include $(TOP)/configs/current
 
-VG_LIBS=-lm -lEGL -lOpenVG -L$(TOP)/lib -L$(TOP)/lib/gallium
+VG_LIBS=-lm -L$(TOP)/$(LIB_DIR) -l$(EGL_LIB) -l$(VG_LIB)
 INCLUDE_DIRS = -I$(TOP)/include $(X11_CFLAGS)
 
 EGLUT_DIR = $(TOP)/progs/egl/eglut
diff --git a/progs/vpglsl/func.glsl b/progs/vpglsl/func.glsl
new file mode 100644 (file)
index 0000000..0553988
--- /dev/null
@@ -0,0 +1,33 @@
+#version 120
+const int KernelSize = 16;
+uniform float KernelValue1f[KernelSize];
+
+
+float add_two(float a, float b)
+{
+    if (a > b)
+        return a - b;
+    else
+        return a + b;
+}
+
+vec4 func(vec4 x)
+{
+    int i;
+    vec4 tmp = gl_Color;
+    vec4 sum = x;
+
+    for (i = 0; i < KernelSize; ++i) {
+        sum = vec4( add_two(sum.x, KernelValue1f[i]) );
+    }
+    return sum;
+}
+
+void main(void)
+{
+    vec4 sum = vec4(0.0);
+
+    sum = func(sum);
+    gl_Position = gl_Vertex;
+    gl_FrontColor = sum;
+}
diff --git a/progs/vpglsl/func2.glsl b/progs/vpglsl/func2.glsl
new file mode 100644 (file)
index 0000000..df964ed
--- /dev/null
@@ -0,0 +1,54 @@
+#version 120
+const int KernelSize = 16;
+uniform float KernelValue1f[KernelSize];
+
+
+float add_two(float a, float b)
+{
+    if (a > b)
+        return a - b;
+    else
+        return a + b;
+}
+
+vec4 myfunc(vec4 x, vec4 mult, vec4 c)
+{
+   if (x.x >= 0.5) {
+      return mult * c;
+   } else {
+      return mult + c;
+   }
+}
+
+vec4 func2(vec4 x)
+{
+    int i;
+    vec4 color = vec4(0);
+       for (i = 0; i < KernelSize; ++i) {
+           vec4 tmp = vec4(1./KernelSize);
+           color += myfunc(x, tmp, gl_Color);
+       }
+    return x * color;
+}
+
+vec4 func(vec4 x)
+{
+    int i;
+    vec4 tmp = gl_Color;
+    vec4 sum = x;
+
+    for (i = 0; i < KernelSize; ++i) {
+        sum = vec4( add_two(sum.x, KernelValue1f[i]) );
+    }
+    sum = func2(sum);
+    return sum;
+}
+
+void main(void)
+{
+    vec4 sum = vec4(0.0);
+
+    sum = func(sum);
+    gl_Position = gl_Vertex;
+    gl_FrontColor = sum;
+}
index c9e3c7bb4b89d0bd367355caf83dc5dc29b83713..b774f504aece416d50f6fe8e83917c200bb162db 100644 (file)
@@ -35,6 +35,7 @@
 
 #define GLX_GLXEXT_PROTOTYPES
 
+#include <assert.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
 #include <GL/gl.h>
@@ -99,6 +100,8 @@ struct visual_attribs
    int accumRedSize, accumGreenSize, accumBlueSize, accumAlphaSize;
    int numSamples, numMultisample;
    int visualCaveat;
+   int floatComponents;
+   int srgb;
 };
 
    
@@ -642,9 +645,29 @@ visual_render_type_name(int type)
          return "rgba|ci";
       default:
          return "";
-      }
+   }
+}
+
+static const char *
+caveat_string(int caveat)
+{
+   switch (caveat) {
+#ifdef GLX_EXT_visual_rating
+      case GLX_SLOW_VISUAL_EXT:
+         return "Slow";
+      case GLX_NON_CONFORMANT_VISUAL_EXT:
+         return "Ncon";
+      case GLX_NONE_EXT:
+         /* fall-through */
+#endif
+      case 0:
+         /* fall-through */
+      default:
+         return "None";
+   }
 }
 
+
 static GLboolean
 get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
                    struct visual_attribs *attribs)
@@ -728,6 +751,12 @@ get_visual_attribs(Display *dpy, XVisualInfo *vInfo,
    attribs->visualCaveat = 0;
 #endif
 
+#if defined(GLX_EXT_framebuffer_sRGB)
+   if (ext && strstr(ext, "GLX_EXT_framebuffer_sRGB")) {
+      glXGetConfig(dpy, vInfo, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &attribs->srgb);
+   }
+#endif
+
    return GL_TRUE;
 }
 
@@ -759,6 +788,7 @@ static GLboolean
 get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
                     struct visual_attribs *attribs)
 {
+   const char *ext = glXQueryExtensionsString(dpy, 0);
    int visual_type;
    XVisualInfo *vInfo;
 
@@ -816,6 +846,24 @@ get_fbconfig_attribs(Display *dpy, GLXFBConfig fbconfig,
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_SAMPLES, &attribs->numSamples);
    glXGetFBConfigAttrib(dpy, fbconfig, GLX_CONFIG_CAVEAT, &attribs->visualCaveat);
 
+#if defined(GLX_NV_float_buffer)
+   if (ext && strstr(ext, "GLX_NV_float_buffer")) {
+      glXGetFBConfigAttrib(dpy, fbconfig, GLX_FLOAT_COMPONENTS_NV, &attribs->floatComponents);
+   }
+#endif
+#if defined(GLX_ARB_fbconfig_float)
+   if (ext && strstr(ext, "GLX_ARB_fbconfig_float")) {
+      if (attribs->render_type & GLX_RGBA_FLOAT_BIT_ARB) {
+         attribs->floatComponents = True;
+      }
+   }
+#endif
+
+#if defined(GLX_EXT_framebuffer_sRGB)
+   if (ext && strstr(ext, "GLX_EXT_framebuffer_sRGB")) {
+      glXGetFBConfigAttrib(dpy, fbconfig, GLX_FRAMEBUFFER_SRGB_CAPABLE_EXT, &attribs->srgb);
+   }
+#endif
    return GL_TRUE;
 }
 
@@ -833,9 +881,11 @@ print_visual_attribs_verbose(const struct visual_attribs *attribs)
           attribs->bufferSize, attribs->level,
          visual_render_type_name(attribs->render_type),
           attribs->doubleBuffer, attribs->stereo);
-   printf("    rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n",
+   printf("    rgba: redSize=%d greenSize=%d blueSize=%d alphaSize=%d float=%c sRGB=%c\n",
           attribs->redSize, attribs->greenSize,
-          attribs->blueSize, attribs->alphaSize);
+          attribs->blueSize, attribs->alphaSize,
+          attribs->floatComponents ? 'Y' : 'N',
+          attribs->srgb ? 'Y' : 'N');
    printf("    auxBuffers=%d depthSize=%d stencilSize=%d\n",
           attribs->auxBuffers, attribs->depthSize, attribs->stencilSize);
    printf("    accum: redSize=%d greenSize=%d blueSize=%d alphaSize=%d\n",
@@ -866,30 +916,18 @@ print_visual_attribs_verbose(const struct visual_attribs *attribs)
 static void
 print_visual_attribs_short_header(void)
 {
- printf("   visual  x  bf lv rg d st colorbuffer ax dp st accumbuffer  ms  cav\n");
- printf(" id dep cl sp sz l  ci b ro  r  g  b  a bf th cl  r  g  b  a ns b eat\n");
- printf("----------------------------------------------------------------------\n");
+ printf("    visual  x   bf lv rg d st  colorbuffer  sr ax dp st accumbuffer  ms  cav\n");
+ printf("  id dep cl sp  sz l  ci b ro  r  g  b  a F gb bf th cl  r  g  b  a ns b eat\n");
+ printf("----------------------------------------------------------------------------\n");
 }
 
 
 static void
 print_visual_attribs_short(const struct visual_attribs *attribs)
 {
-   char *caveat = NULL;
-#ifdef GLX_EXT_visual_rating
-   if (attribs->visualCaveat == GLX_NONE_EXT || attribs->visualCaveat == 0)
-      caveat = "None";
-   else if (attribs->visualCaveat == GLX_SLOW_VISUAL_EXT)
-      caveat = "Slow";
-   else if (attribs->visualCaveat == GLX_NON_CONFORMANT_VISUAL_EXT)
-      caveat = "Ncon";
-   else
-      caveat = "None";
-#else
-   caveat = "None";
-#endif 
+   const char *caveat = caveat_string(attribs->visualCaveat);
 
-   printf("0x%02x %2d %2s %2d %2d %2d %c%c %c  %c %2d %2d %2d %2d %2d %2d %2d",
+   printf("0x%03x %2d %2s %2d %3d %2d %c%c %c %c  %2d %2d %2d %2d %c  %c %2d %2d %2d",
           attribs->id,
           attribs->depth,
           visual_class_abbrev(attribs->klass),
@@ -902,6 +940,8 @@ print_visual_attribs_short(const struct visual_attribs *attribs)
           attribs->stereo ? 'y' : '.',
           attribs->redSize, attribs->greenSize,
           attribs->blueSize, attribs->alphaSize,
+          attribs->floatComponents ? 'f' : '.',
+          attribs->srgb ? 's' : '.',
           attribs->auxBuffers,
           attribs->depthSize,
           attribs->stencilSize
@@ -919,16 +959,18 @@ print_visual_attribs_short(const struct visual_attribs *attribs)
 static void
 print_visual_attribs_long_header(void)
 {
- printf("Vis  Vis   Visual Trans  buff lev render DB ste  r   g   b   a  aux dep ste  accum buffers  MS   MS\n");
- printf(" ID Depth   Type  parent size el   type     reo sz  sz  sz  sz  buf th  ncl  r   g   b   a  num bufs\n");
- printf("----------------------------------------------------------------------------------------------------\n");
+ printf("Vis   Vis   Visual Trans  buff lev render DB ste  r   g   b   a      s  aux dep ste  accum buffer   MS   MS         \n");
+ printf(" ID  Depth   Type  parent size el   type     reo sz  sz  sz  sz flt rgb buf th  ncl  r   g   b   a  num bufs caveats\n");
+ printf("--------------------------------------------------------------------------------------------------------------------\n");
 }
 
 
 static void
 print_visual_attribs_long(const struct visual_attribs *attribs)
 {
-   printf("0x%2x %2d %-11s %2d     %2d %2d  %4s %3d %3d %3d %3d %3d %3d",
+   const char *caveat = caveat_string(attribs->visualCaveat);
+
+   printf("0x%3x %2d %-11s %2d    %3d %2d  %4s %3d %3d %3d %3d %3d %3d",
           attribs->id,
           attribs->depth,
           visual_class_name(attribs->klass),
@@ -942,13 +984,16 @@ print_visual_attribs_long(const struct visual_attribs *attribs)
           attribs->blueSize, attribs->alphaSize
           );
 
-   printf(" %3d %4d %2d %3d %3d %3d %3d  %2d  %2d\n",
+   printf("  %c   %c %3d %4d %2d %3d %3d %3d %3d  %2d  %2d %6s\n",
+          attribs->floatComponents ? 'f' : '.',
+          attribs->srgb ? 's' : '.',
           attribs->auxBuffers,
           attribs->depthSize,
           attribs->stencilSize,
           attribs->accumRedSize, attribs->accumGreenSize,
           attribs->accumBlueSize, attribs->accumAlphaSize,
-          attribs->numSamples, attribs->numMultisample
+          attribs->numSamples, attribs->numMultisample,
+          caveat
           );
 }
 
index ca2f7d5b3ad03f0d70fdc45d3eaf75b100e9afcf..08e82c65e9beb964586a8cae3f4ee40f8c7b7561 100644 (file)
@@ -26,7 +26,7 @@ $(EGL_DRIVER): $(EGL_OBJECTS) Makefile $(TOP)/src/egl/drivers/Makefile.template
        @$(MKLIB) -o $(EGL_DRIVER) -noprefix \
                -linker '$(CC)' -ldflags '$(LDFLAGS)' \
                -L$(TOP)/$(LIB_DIR) $(MKLIB_OPTIONS) \
-               $(EGL_OBJECTS) $(EGL_LIBS)
+               $(EGL_OBJECTS) $(EGL_LIBS) -l$(EGL_LIB)
 
 .c.o:
        $(CC) -c $(EGL_INCLUDES) $(CFLAGS) $(EGL_CFLAGS) $< -o $@
index 82f409d294bb8524c1d5c146caa0ce7dcac75dc1..eb9a6510ed0c282c27d581d8cd3d7e96d080a892 100644 (file)
@@ -165,7 +165,7 @@ EGLint dri2_to_egl_attribute_map[] = {
    0,                          /* __DRI_ATTRIB_BIND_TO_TEXTURE_RGBA */
    0,                          /* __DRI_ATTRIB_BIND_TO_MIPMAP_TEXTURE */
    0,                          /* __DRI_ATTRIB_BIND_TO_TEXTURE_TARGETS */
-   0,                          /* __DRI_ATTRIB_YINVERTED */
+   EGL_Y_INVERTED_NOK,         /* __DRI_ATTRIB_YINVERTED */
 };
 
 static void
@@ -417,12 +417,6 @@ dri2_get_buffers_with_format(__DRIdrawable * driDrawable,
    return dri2_surf->buffers;
 }
 
-#ifdef GLX_USE_TLS
-static const char dri_driver_format[] = "%.*s/tls/%s_dri.so";
-#else
-static const char dri_driver_format[] = "%.*s/%s_dri.so";
-#endif
-
 static const char dri_driver_path[] = DEFAULT_DRIVER_DIR;
 
 struct dri2_extension_match {
@@ -680,15 +674,24 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
    dri2_dpy->driver = NULL;
    end = search_paths + strlen(search_paths);
    for (p = search_paths; p < end && dri2_dpy->driver == NULL; p = next + 1) {
+      int len;
       next = strchr(p, ':');
       if (next == NULL)
          next = end;
 
+      len = next - p;
+#if GLX_USE_TLS
       snprintf(path, sizeof path,
-              dri_driver_format, (int) (next - p), p, dri2_dpy->driver_name);
+              "%.*s/tls/%s_dri.so", len, p, dri2_dpy->driver_name);
       dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
-      if (dri2_dpy->driver == NULL)
-        _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror());
+#endif
+      if (dri2_dpy->driver == NULL) {
+        snprintf(path, sizeof path,
+                 "%.*s/%s_dri.so", len, p, dri2_dpy->driver_name);
+        dri2_dpy->driver = dlopen(path, RTLD_NOW | RTLD_GLOBAL);
+        if (dri2_dpy->driver == NULL)
+           _eglLog(_EGL_DEBUG, "failed to open %s: %s\n", path, dlerror());
+      }
    }
 
    if (dri2_dpy->driver == NULL) {
@@ -781,6 +784,7 @@ dri2_initialize(_EGLDriver *drv, _EGLDisplay *disp,
    disp->Extensions.KHR_gl_renderbuffer_image = EGL_TRUE;
    disp->Extensions.KHR_gl_texture_2D_image = EGL_TRUE;
    disp->Extensions.NOK_swap_region = EGL_TRUE;
+   disp->Extensions.NOK_texture_from_pixmap = EGL_TRUE;
 
    /* we're supporting EGL 1.4 */
    *major = 1;
@@ -1229,19 +1233,8 @@ dri2_bind_tex_image(_EGLDriver *drv,
    ctx = _eglGetCurrentContext();
    dri2_ctx = dri2_egl_context(ctx);
 
-   if (buffer != EGL_BACK_BUFFER) {
-      _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
+   if (!_eglBindTexImage(drv, disp, surf, buffer))
       return EGL_FALSE;
-   }
-
-   /* We allow binding pixmaps too... Not conformat, but we can do it
-    * for free and it's useful for X compositors.  Supposedly there's
-    * a EGL_NOKIA_texture_from_pixmap extension that allows that, but
-    * I couldn't find it at this time. */
-   if ((dri2_surf->base.Type & (EGL_PBUFFER_BIT | EGL_PIXMAP_BIT)) == 0) {
-      _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
-      return EGL_FALSE;
-   }
 
    switch (dri2_surf->base.TextureFormat) {
    case EGL_TEXTURE_RGB:
@@ -1251,8 +1244,7 @@ dri2_bind_tex_image(_EGLDriver *drv,
       format = __DRI_TEXTURE_FORMAT_RGBA;
       break;
    default:
-      _eglError(EGL_BAD_MATCH, "eglBindTexImage");
-      return EGL_FALSE;
+      assert(0);
    }
 
    switch (dri2_surf->base.TextureTarget) {
@@ -1260,15 +1252,14 @@ dri2_bind_tex_image(_EGLDriver *drv,
       target = GL_TEXTURE_2D;
       break;
    default:
-      _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
-      return EGL_FALSE;
+      assert(0);
    }
 
    (*dri2_dpy->tex_buffer->setTexBuffer2)(dri2_ctx->dri_context,
                                          target, format,
                                          dri2_surf->dri_drawable);
 
-   return dri2_surf->base.BoundToTexture = EGL_TRUE;
+   return EGL_TRUE;
 }
 
 static EGLBoolean
index 3cbfebe4881cd61e1211aa3266e553dd299c0b8f..e08ef5f2228111f3d387190b2be41f193bd7c322 100644 (file)
@@ -41,6 +41,7 @@
 #include "eglconfigutil.h"
 #include "eglconfig.h"
 #include "eglcontext.h"
+#include "egldefines.h"
 #include "egldisplay.h"
 #include "egldriver.h"
 #include "eglcurrent.h"
@@ -48,7 +49,6 @@
 #include "eglsurface.h"
 
 #define CALLOC_STRUCT(T)   (struct T *) calloc(1, sizeof(struct T))
-#define ARRAY_SIZE(a)      (sizeof(a) / sizeof(a[0]))
 
 #ifndef GLX_VERSION_1_4
 #error "GL/glx.h must be equal to or greater than GLX 1.4"
index 923992da48bc3c47bdbf6bbf65938daf789fc3e2..1a533e0880ba9a61b867dbe90e3d50d6ee7ccf1d 100644 (file)
@@ -261,7 +261,7 @@ EGLBoolean EGLAPIENTRY
 eglInitialize(EGLDisplay dpy, EGLint *major, EGLint *minor)
 {
    _EGLDisplay *disp = _eglLockDisplay(dpy);
-   EGLint major_int, minor_int;
+   EGLint major_int = 0, minor_int = 0;
 
    if (!disp)
       RETURN_EGL_ERROR(NULL, EGL_BAD_DISPLAY, EGL_FALSE);
index 47513a4edb29556c4d2956e9606f2072d7b5194d..fa947d7688759510eb80640b8346eaf5d27ba238 100644 (file)
@@ -223,7 +223,12 @@ static const struct {
                                     0 },
    { EGL_NONE,                      ATTRIB_TYPE_PSEUDO,
                                     ATTRIB_CRITERION_IGNORE,
-                                    0 }
+                                    0 },
+
+   { EGL_Y_INVERTED_NOK,            ATTRIB_TYPE_BOOLEAN,
+                                    ATTRIB_CRITERION_EXACT,
+                                    EGL_DONT_CARE },
+
 };
 
 
@@ -478,6 +483,28 @@ _eglMatchConfig(const _EGLConfig *conf, const _EGLConfig *criteria)
    return matched;
 }
 
+static INLINE EGLBoolean
+_eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
+{
+   if (_eglIndexConfig(conf, attr) < 0)
+      return EGL_FALSE;
+
+   /* there are some holes in the range */
+   switch (attr) {
+   case 0x3030 /* a gap before EGL_SAMPLES */:
+   case EGL_NONE:
+#ifdef EGL_VERSION_1_4
+   case EGL_MATCH_NATIVE_PIXMAP:
+#endif
+      return EGL_FALSE;
+   case EGL_Y_INVERTED_NOK:
+      return conf->Display->Extensions.NOK_texture_from_pixmap;
+   default:
+      break;
+   }
+
+   return EGL_TRUE;
+}
 
 /**
  * Initialize a criteria config from the given attribute list.
@@ -500,15 +527,13 @@ _eglParseConfigAttribList(_EGLConfig *conf, const EGLint *attrib_list)
 
    /* parse the list */
    for (i = 0; attrib_list && attrib_list[i] != EGL_NONE; i += 2) {
-      EGLint idx;
-
       attr = attrib_list[i];
       val = attrib_list[i + 1];
 
-      idx = _eglIndexConfig(conf, attr);
-      if (idx < 0)
-         return EGL_FALSE;
-      conf->Storage[idx] = val;
+      if (!_eglIsConfigAttribValid(conf, attr))
+        return EGL_FALSE;
+             
+      SET_CONFIG_ATTRIB(conf, attr, val);
 
       /* rememeber some attributes for post-processing */
       switch (attr) {
@@ -781,28 +806,6 @@ _eglChooseConfig(_EGLDriver *drv, _EGLDisplay *disp, const EGLint *attrib_list,
 }
 
 
-static INLINE EGLBoolean
-_eglIsConfigAttribValid(_EGLConfig *conf, EGLint attr)
-{
-   if (_eglIndexConfig(conf, attr) < 0)
-      return EGL_FALSE;
-
-   /* there are some holes in the range */
-   switch (attr) {
-   case 0x3030 /* a gap before EGL_SAMPLES */:
-   case EGL_NONE:
-#ifdef EGL_VERSION_1_4
-   case EGL_MATCH_NATIVE_PIXMAP:
-#endif
-      return EGL_FALSE;
-   default:
-      break;
-   }
-
-   return EGL_TRUE;
-}
-
-
 /**
  * Fallback for eglGetConfigAttrib.
  */
index ced060f7797bece2408a75b15645ca418403b45c..ca63c40d3d78b26468638bc58b61eaa4fd4706f8 100644 (file)
@@ -8,16 +8,24 @@
 
 #define _EGL_CONFIG_FIRST_ATTRIB EGL_BUFFER_SIZE
 #define _EGL_CONFIG_LAST_ATTRIB EGL_CONFORMANT
-#define _EGL_CONFIG_NUM_ATTRIBS \
+#define _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS \
    (_EGL_CONFIG_LAST_ATTRIB - _EGL_CONFIG_FIRST_ATTRIB + 1)
 
-#define _EGL_CONFIG_STORAGE_SIZE _EGL_CONFIG_NUM_ATTRIBS
+/* Attributes outside the contiguous block:
+ *
+ *   EGL_Y_INVERTED_NOK
+ */
+#define _EGL_CONFIG_FIRST_EXTRA_ATTRIB _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS
+#define _EGL_CONFIG_NUM_EXTRA_ATTRIBS 1
+
+#define _EGL_CONFIG_NUM_ATTRIBS \
+   _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS + _EGL_CONFIG_NUM_EXTRA_ATTRIBS
 
 
 struct _egl_config
 {
    _EGLDisplay *Display;
-   EGLint Storage[_EGL_CONFIG_STORAGE_SIZE];
+   EGLint Storage[_EGL_CONFIG_NUM_ATTRIBS];
 };
 
 
@@ -37,10 +45,15 @@ _eglIndexConfig(const _EGLConfig *conf, EGLint key)
 {
    (void) conf;
    if (key >= _EGL_CONFIG_FIRST_ATTRIB &&
-       key < _EGL_CONFIG_FIRST_ATTRIB + _EGL_CONFIG_NUM_ATTRIBS)
+       key < _EGL_CONFIG_FIRST_ATTRIB + _EGL_CONFIG_NUM_CONTIGUOUS_ATTRIBS)
       return key - _EGL_CONFIG_FIRST_ATTRIB;
-   else
+   
+   switch (key) {
+   case EGL_Y_INVERTED_NOK:
+      return _EGL_CONFIG_FIRST_EXTRA_ATTRIB;
+   default:
       return -1;
+   }
 }
 
 
index 0b7f9d83036c072e3cd5ffb077b01296ae7319a9..42e305f91ac34073d248f6ad19ff86377d782b1b 100644 (file)
@@ -47,6 +47,7 @@ struct _egl_extensions
    EGLBoolean KHR_gl_texture_3D_image;
    EGLBoolean KHR_gl_renderbuffer_image;
    EGLBoolean NOK_swap_region;
+   EGLBoolean NOK_texture_from_pixmap;
 
    char String[_EGL_MAX_EXTENSIONS_LEN];
 };
index 82ddb6cad99e633274d9aadecaefbfa99105550c..e62a9e7de8ce1e13bede66e6be4fc0cbca432f19 100644 (file)
@@ -97,6 +97,7 @@ _eglUpdateExtensionsString(_EGLDisplay *dpy)
    _EGL_CHECK_EXTENSION(KHR_gl_renderbuffer_image);
 
    _EGL_CHECK_EXTENSION(NOK_swap_region);
+   _EGL_CHECK_EXTENSION(NOK_texture_from_pixmap);
 #undef _EGL_CHECK_EXTENSION
 }
 
index 8026a6314d3629e83acd47f1fea527770528b35a..d46bdb0672e9659901196ab9b974c9ef433cbd3b 100644 (file)
@@ -36,12 +36,17 @@ _eglClampSwapInterval(_EGLSurface *surf, EGLint interval)
 static EGLint
 _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
 {
+   _EGLDisplay *dpy = surf->Resource.Display;
    EGLint type = surf->Type;
+   EGLint texture_type = EGL_PBUFFER_BIT;
    EGLint i, err = EGL_SUCCESS;
 
    if (!attrib_list)
       return EGL_SUCCESS;
 
+   if (dpy->Extensions.NOK_texture_from_pixmap)
+      texture_type |= EGL_PIXMAP_BIT;
+
    for (i = 0; attrib_list[i] != EGL_NONE; i++) {
       EGLint attr = attrib_list[i++];
       EGLint val = attrib_list[i];
@@ -125,7 +130,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
          surf->LargestPbuffer = !!val;
          break;
       case EGL_TEXTURE_FORMAT:
-         if (type != EGL_PBUFFER_BIT) {
+         if (!(type & texture_type)) {
             err = EGL_BAD_ATTRIBUTE;
             break;
          }
@@ -143,7 +148,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
          surf->TextureFormat = val;
          break;
       case EGL_TEXTURE_TARGET:
-         if (type != EGL_PBUFFER_BIT) {
+         if (!(type & texture_type)) {
             err = EGL_BAD_ATTRIBUTE;
             break;
          }
@@ -160,7 +165,7 @@ _eglParseSurfaceAttribList(_EGLSurface *surf, const EGLint *attrib_list)
          surf->TextureTarget = val;
          break;
       case EGL_MIPMAP_TEXTURE:
-         if (type != EGL_PBUFFER_BIT) {
+         if (!(type & texture_type)) {
             err = EGL_BAD_ATTRIBUTE;
             break;
          }
@@ -452,11 +457,16 @@ EGLBoolean
 _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
                  EGLint buffer)
 {
+   EGLint texture_type = EGL_PBUFFER_BIT;
+
    /* Just do basic error checking and return success/fail.
     * Drivers must implement the real stuff.
     */
 
-   if (surface->Type != EGL_PBUFFER_BIT) {
+   if (dpy->Extensions.NOK_texture_from_pixmap)
+      texture_type |= EGL_PIXMAP_BIT;
+
+   if (!(surface->Type & texture_type)) {
       _eglError(EGL_BAD_SURFACE, "eglBindTexImage");
       return EGL_FALSE;
    }
@@ -466,6 +476,11 @@ _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surface,
       return EGL_FALSE;
    }
 
+   if (surface->TextureTarget == EGL_NO_TEXTURE) {
+      _eglError(EGL_BAD_MATCH, "eglBindTexImage");
+      return EGL_FALSE;
+   }
+
    if (buffer != EGL_BACK_BUFFER) {
       _eglError(EGL_BAD_PARAMETER, "eglBindTexImage");
       return EGL_FALSE;
index 0a00035730f73731fa5ecdb89e24500e19a49171..8f520dcdf650f606d0cdf54d0879be2772df0159 100644 (file)
@@ -83,7 +83,7 @@ extern EGLBoolean
 _eglSurfaceAttrib(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint attribute, EGLint value);
 
 
-extern EGLBoolean
+PUBLIC extern EGLBoolean
 _eglBindTexImage(_EGLDriver *drv, _EGLDisplay *dpy, _EGLSurface *surf, EGLint buffer);
 
 
index 02e6ea7a9f769f86c79676e49fd79b81fe95e99f..e5e9578b5e4fef321498a942eda720ed324c3743 100644 (file)
@@ -25,4 +25,4 @@ SConscript('targets/SConscript')
 
 if platform != 'embedded':
        SConscript('tests/unit/SConscript')
-       SConscript('tests/graw/SConscript')
+       #SConscript('tests/graw/SConscript')
index 05b187805b161afacbb0252cd03854669a8f8564..7ea51621f72a7faa52ef272d1299b3adc68b93b3 100644 (file)
@@ -12,6 +12,7 @@
 #include "gallivm/lp_bld_printf.h"
 
 #include "tgsi/tgsi_exec.h"
+#include "tgsi/tgsi_dump.h"
 
 #include "util/u_cpu_detect.h"
 #include "util/u_string.h"
@@ -214,27 +215,34 @@ draw_llvm_create(struct draw_context *draw)
 
    llvm->pass = LLVMCreateFunctionPassManager(llvm->provider);
    LLVMAddTargetData(llvm->target, llvm->pass);
-   /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
-    * but there are more on SVN. */
-   /* TODO: Add more passes */
-   LLVMAddCFGSimplificationPass(llvm->pass);
-   LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
-   LLVMAddConstantPropagationPass(llvm->pass);
-   if(util_cpu_caps.has_sse4_1) {
-      /* FIXME: There is a bug in this pass, whereby the combination of fptosi
-       * and sitofp (necessary for trunc/floor/ceil/round implementation)
-       * somehow becomes invalid code.
+
+   if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
+      /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
+       * but there are more on SVN. */
+      /* TODO: Add more passes */
+      LLVMAddCFGSimplificationPass(llvm->pass);
+      LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
+      LLVMAddConstantPropagationPass(llvm->pass);
+      if(util_cpu_caps.has_sse4_1) {
+         /* FIXME: There is a bug in this pass, whereby the combination of fptosi
+          * and sitofp (necessary for trunc/floor/ceil/round implementation)
+          * somehow becomes invalid code.
+          */
+         LLVMAddInstructionCombiningPass(llvm->pass);
+      }
+      LLVMAddGVNPass(llvm->pass);
+   } else {
+      /* We need at least this pass to prevent the backends to fail in
+       * unexpected ways.
        */
-      LLVMAddInstructionCombiningPass(llvm->pass);
+      LLVMAddPromoteMemoryToRegisterPass(llvm->pass);
    }
-   LLVMAddGVNPass(llvm->pass);
 
    init_globals(llvm);
 
-
-#if 0
-   LLVMDumpModule(lp_build_module);
-#endif
+   if (gallivm_debug & GALLIVM_DEBUG_IR) {
+      LLVMDumpModule(llvm->module);
+   }
 
    return llvm;
 }
@@ -283,7 +291,10 @@ generate_vs(struct draw_llvm *llvm,
    num_vs = 4;              /* number of vertices per block */
 #endif
 
-   /*tgsi_dump(tokens, 0);*/
+   if (gallivm_debug & GALLIVM_DEBUG_IR) {
+      tgsi_dump(tokens, 0);
+   }
+
    lp_build_tgsi_soa(builder,
                      tokens,
                      vs_type,
@@ -727,7 +738,7 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
 
    LLVMRunFunctionPassManager(llvm->pass, variant->function);
 
-   if (0) {
+   if (gallivm_debug & GALLIVM_DEBUG_IR) {
       lp_debug_dump_value(variant->function);
       debug_printf("\n");
    }
@@ -735,8 +746,9 @@ draw_llvm_generate(struct draw_llvm *llvm, struct draw_llvm_variant *variant)
    code = LLVMGetPointerToGlobal(llvm->draw->engine, variant->function);
    variant->jit_func = voidptr_to_draw_jit_vert_func(code);
 
-   if (0)
+   if (gallivm_debug & GALLIVM_DEBUG_ASM) {
       lp_disassemble(code);
+   }
 }
 
 
@@ -881,7 +893,7 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
 
    LLVMRunFunctionPassManager(llvm->pass, variant->function_elts);
 
-   if (0) {
+   if (gallivm_debug & GALLIVM_DEBUG_IR) {
       lp_debug_dump_value(variant->function_elts);
       debug_printf("\n");
    }
@@ -889,8 +901,9 @@ draw_llvm_generate_elts(struct draw_llvm *llvm, struct draw_llvm_variant *varian
    code = LLVMGetPointerToGlobal(llvm->draw->engine, variant->function_elts);
    variant->jit_func_elts = voidptr_to_draw_vert_func_elts(code);
 
-   if (0)
+   if (gallivm_debug & GALLIVM_DEBUG_ASM) {
       lp_disassemble(code);
+   }
 }
 
 void
index 1897acce795403e35d1fb37d559cb4ec60298015..858002b34feda33fb79b838242f9c067e4083504 100644 (file)
 #include "util/u_string.h"
 
 
+#define GALLIVM_DEBUG_TGSI      0x1
+#define GALLIVM_DEBUG_IR        0x2
+#define GALLIVM_DEBUG_ASM       0x4
+#define GALLIVM_DEBUG_NO_OPT    0x8
+
+
+#ifdef DEBUG
+extern unsigned gallivm_debug;
+#else
+#define gallivm_debug 0
+#endif
+
+
 static INLINE void
 lp_build_name(LLVMValueRef val, const char *format, ...)
 {
index 560ce1de73f558f1d568e2b2bc212b83a78d6389..823a8ec7b70519404b696a373dfcaeaea532f557 100644 (file)
@@ -843,7 +843,7 @@ lp_build_alloca(LLVMBuilderRef builder,
  * first block may prevent the X86 backend from successfully align the stack as
  * required.
  *
- * Also the scalarrepl pass is supossedly more powerful and can promote
+ * Also the scalarrepl pass is supposedly more powerful and can promote
  * arrays in many cases.
  *
  * See also:
index a2b0298a1c7267392a187023a0078ce6523767ef..e1b94adc85a4a070cdd86e34ff0971610d294113 100644 (file)
@@ -89,6 +89,11 @@ lp_build_format_swizzle_soa(const struct util_format_description *format_desc,
  * It requires that a packed pixel fits into an element of the output
  * channels. The common case is when converting pixel with a depth of 32 bit or
  * less into floats.
+ *
+ * \param format_desc  the format of the 'packed' incoming pixel vector
+ * \param type  the desired type for rgba_out (type.length = n, above)
+ * \param packed  the incoming vector of packed pixels
+ * \param rgba_out  returns the SoA R,G,B,A vectors
  */
 void
 lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
@@ -115,8 +120,8 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
    /* Decode the input vector components */
    start = 0;
    for (chan = 0; chan < format_desc->nr_channels; ++chan) {
-      unsigned width = format_desc->channel[chan].size;
-      unsigned stop = start + width;
+      const unsigned width = format_desc->channel[chan].size;
+      const unsigned stop = start + width;
       LLVMValueRef input;
 
       input = packed;
@@ -247,9 +252,10 @@ lp_build_unpack_rgba_soa(LLVMBuilderRef builder,
 
 
 /**
- * Fetch a pixel into a SoA.
+ * Fetch a texels from a texture, returning them in SoA layout.
  *
- * \param type  the desired return type for 'rgba'
+ * \param type  the desired return type for 'rgba'.  The vector length
+ *              is the number of texels to fetch
  *
  * \param base_ptr  points to start of the texture image block.  For non-
  *                  compressed formats, this simply points to the texel.
@@ -290,6 +296,7 @@ lp_build_fetch_rgba_soa(LLVMBuilderRef builder,
 
       /*
        * gather the texels from the texture
+       * Ex: packed = {BGRA, BGRA, BGRA, BGRA}.
        */
       packed = lp_build_gather(builder,
                                type.length,
index 5067d0a164f4cf7b9d3ee5c3483ad59ec6054c58..bd080f397aa0f73907a4ae67a8f7c3d7773a9629 100644 (file)
 #include "pipe/p_compiler.h"
 #include "util/u_cpu_detect.h"
 #include "util/u_debug.h"
+#include "lp_bld_debug.h"
 #include "lp_bld_init.h"
 
 
+#ifdef DEBUG
+unsigned gallivm_debug = 0;
+
+static const struct debug_named_value lp_bld_debug_flags[] = {
+   { "tgsi",   GALLIVM_DEBUG_TGSI },
+   { "ir",     GALLIVM_DEBUG_IR },
+   { "asm",    GALLIVM_DEBUG_ASM },
+   { "nopt",   GALLIVM_DEBUG_NO_OPT },
+   {NULL, 0}
+};
+#endif
+
+
 LLVMModuleRef lp_build_module = NULL;
 LLVMExecutionEngineRef lp_build_engine = NULL;
 LLVMModuleProviderRef lp_build_provider = NULL;
@@ -41,6 +55,10 @@ LLVMTargetDataRef lp_build_target = NULL;
 void
 lp_build_init(void)
 {
+#ifdef DEBUG
+   gallivm_debug = debug_get_flags_option("GALLIVM_DEBUG", lp_bld_debug_flags, 0 );
+#endif
+
    LLVMInitializeNativeTarget();
 
    LLVMLinkInJIT();
index aaf3360aa245b4b974496e986420036388f9f215..40ea94c493537f4838c94d0f80eefd8ec68fcf69 100644 (file)
@@ -81,6 +81,8 @@
 #define QUAD_BOTTOM_LEFT  2
 #define QUAD_BOTTOM_RIGHT 3
 
+#define LP_MAX_INSTRUCTIONS 256
+
 
 struct lp_exec_mask {
    struct lp_build_context *bld;
@@ -105,6 +107,13 @@ struct lp_exec_mask {
    } loop_stack[LP_MAX_TGSI_NESTING];
    int loop_stack_size;
 
+   LLVMValueRef ret_mask;
+   struct {
+      int pc;
+      LLVMValueRef ret_mask;
+   } call_stack[LP_MAX_TGSI_NESTING];
+   int call_stack_size;
+
    LLVMValueRef exec_mask;
 };
 
@@ -134,6 +143,9 @@ struct lp_build_tgsi_soa_context
 
    struct lp_build_mask_context *mask;
    struct lp_exec_mask exec_mask;
+
+   struct tgsi_full_instruction *instructions;
+   uint max_instructions;
 };
 
 static const unsigned char
@@ -166,9 +178,10 @@ static void lp_exec_mask_init(struct lp_exec_mask *mask, struct lp_build_context
    mask->has_mask = FALSE;
    mask->cond_stack_size = 0;
    mask->loop_stack_size = 0;
+   mask->call_stack_size = 0;
 
    mask->int_vec_type = lp_build_int_vec_type(mask->bld->type);
-   mask->break_mask = mask->cont_mask = mask->cond_mask =
+   mask->exec_mask = mask->ret_mask = mask->break_mask = mask->cont_mask = mask->cond_mask =
          LLVMConstAllOnes(mask->int_vec_type);
 }
 
@@ -189,9 +202,16 @@ static void lp_exec_mask_update(struct lp_exec_mask *mask)
    } else
       mask->exec_mask = mask->cond_mask;
 
+   if (mask->call_stack_size) {
+      mask->exec_mask = LLVMBuildAnd(mask->bld->builder,
+                                     mask->exec_mask,
+                                     mask->ret_mask,
+                                     "callmask");
+   }
 
    mask->has_mask = (mask->cond_stack_size > 0 ||
-                     mask->loop_stack_size > 0);
+                     mask->loop_stack_size > 0 ||
+                     mask->call_stack_size > 0);
 }
 
 static void lp_exec_mask_cond_push(struct lp_exec_mask *mask,
@@ -368,6 +388,49 @@ static void lp_exec_mask_store(struct lp_exec_mask *mask,
       LLVMBuildStore(mask->bld->builder, val, dst);
 }
 
+static void lp_exec_mask_call(struct lp_exec_mask *mask,
+                              int func,
+                              int *pc)
+{
+   assert(mask->call_stack_size < LP_MAX_TGSI_NESTING);
+   mask->call_stack[mask->call_stack_size].pc = *pc;
+   mask->call_stack[mask->call_stack_size].ret_mask = mask->ret_mask;
+   mask->call_stack_size++;
+   *pc = func;
+}
+
+static void lp_exec_mask_ret(struct lp_exec_mask *mask, int *pc)
+{
+   LLVMValueRef exec_mask;
+
+   if (mask->call_stack_size == 0) {
+      /* returning from main() */
+      *pc = -1;
+      return;
+   }
+   exec_mask = LLVMBuildNot(mask->bld->builder,
+                            mask->exec_mask,
+                            "ret");
+
+   mask->ret_mask = LLVMBuildAnd(mask->bld->builder,
+                                 mask->ret_mask,
+                                 exec_mask, "ret_full");
+
+   lp_exec_mask_update(mask);
+}
+
+static void lp_exec_mask_bgnsub(struct lp_exec_mask *mask)
+{
+}
+
+static void lp_exec_mask_endsub(struct lp_exec_mask *mask, int *pc)
+{
+   assert(mask->call_stack_size);
+   mask->call_stack_size--;
+   *pc = mask->call_stack[mask->call_stack_size].pc;
+   mask->ret_mask = mask->call_stack[mask->call_stack_size].ret_mask;
+   lp_exec_mask_update(mask);
+}
 
 static LLVMValueRef
 emit_ddx(struct lp_build_tgsi_soa_context *bld,
@@ -418,34 +481,36 @@ emit_fetch(
    const unsigned chan_index )
 {
    const struct tgsi_full_src_register *reg = &inst->Src[index];
-   unsigned swizzle = tgsi_util_get_full_src_register_swizzle( reg, chan_index );
+   const unsigned swizzle =
+      tgsi_util_get_full_src_register_swizzle(reg, chan_index);
    LLVMValueRef res;
    LLVMValueRef addr = NULL;
 
-   switch (swizzle) {
-   case TGSI_SWIZZLE_X:
-   case TGSI_SWIZZLE_Y:
-   case TGSI_SWIZZLE_Z:
-   case TGSI_SWIZZLE_W:
-
-      if (reg->Register.Indirect) {
-         LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
-         unsigned swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, chan_index );
-         addr = LLVMBuildLoad(bld->base.builder,
-                              bld->addr[reg->Indirect.Index][swizzle],
-                              "");
-         /* for indexing we want integers */
-         addr = LLVMBuildFPToSI(bld->base.builder, addr,
-                                int_vec_type, "");
-         addr = LLVMBuildExtractElement(bld->base.builder,
-                                        addr, LLVMConstInt(LLVMInt32Type(), 0, 0),
-                                        "");
-         addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0));
-      }
-
-      switch (reg->Register.File) {
-      case TGSI_FILE_CONSTANT: {
-         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(), reg->Register.Index*4 + swizzle, 0);
+   if (swizzle > 3) {
+      assert(0 && "invalid swizzle in emit_fetch()");
+      return bld->base.undef;
+   }
+
+   if (reg->Register.Indirect) {
+      LLVMTypeRef int_vec_type = lp_build_int_vec_type(bld->base.type);
+      unsigned swizzle = tgsi_util_get_src_register_swizzle( &reg->Indirect, chan_index );
+      addr = LLVMBuildLoad(bld->base.builder,
+                           bld->addr[reg->Indirect.Index][swizzle],
+                           "");
+      /* for indexing we want integers */
+      addr = LLVMBuildFPToSI(bld->base.builder, addr,
+                             int_vec_type, "");
+      addr = LLVMBuildExtractElement(bld->base.builder,
+                                     addr, LLVMConstInt(LLVMInt32Type(), 0, 0),
+                                     "");
+      addr = lp_build_mul(&bld->base, addr, LLVMConstInt(LLVMInt32Type(), 4, 0));
+   }
+
+   switch (reg->Register.File) {
+   case TGSI_FILE_CONSTANT:
+      {
+         LLVMValueRef index = LLVMConstInt(LLVMInt32Type(),
+                                           reg->Register.Index*4 + swizzle, 0);
          LLVMValueRef scalar, scalar_ptr;
 
          if (reg->Register.Indirect) {
@@ -453,24 +518,26 @@ emit_fetch(
               "\taddr = %d\n", addr);*/
             index = lp_build_add(&bld->base, index, addr);
          }
-         scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr, &index, 1, "");
+         scalar_ptr = LLVMBuildGEP(bld->base.builder, bld->consts_ptr,
+                                   &index, 1, "");
          scalar = LLVMBuildLoad(bld->base.builder, scalar_ptr, "");
 
          res = lp_build_broadcast_scalar(&bld->base, scalar);
-         break;
       }
+      break;
 
-      case TGSI_FILE_IMMEDIATE:
-         res = bld->immediates[reg->Register.Index][swizzle];
-         assert(res);
-         break;
+   case TGSI_FILE_IMMEDIATE:
+      res = bld->immediates[reg->Register.Index][swizzle];
+      assert(res);
+      break;
 
-      case TGSI_FILE_INPUT:
-         res = bld->inputs[reg->Register.Index][swizzle];
-         assert(res);
-         break;
+   case TGSI_FILE_INPUT:
+      res = bld->inputs[reg->Register.Index][swizzle];
+      assert(res);
+      break;
 
-      case TGSI_FILE_TEMPORARY: {
+   case TGSI_FILE_TEMPORARY:
+      {
          LLVMValueRef temp_ptr = get_temp_ptr(bld, reg->Register.Index,
                                               swizzle,
                                               reg->Register.Indirect,
@@ -478,17 +545,11 @@ emit_fetch(
          res = LLVMBuildLoad(bld->base.builder, temp_ptr, "");
          if(!res)
             return bld->base.undef;
-         break;
-      }
-
-      default:
-         assert( 0 );
-         return bld->base.undef;
       }
       break;
 
    default:
-      assert( 0 );
+      assert(0 && "invalid src register in emit_fetch()");
       return bld->base.undef;
    }
 
@@ -892,10 +953,10 @@ emit_declaration(
       case TGSI_FILE_TEMPORARY:
          assert(idx < LP_MAX_TGSI_TEMPS);
          if (bld->has_indirect_addressing) {
-            LLVMValueRef val = LLVMConstInt(LLVMInt32Type(),
-                                            last*4 + 4, 0);
+            LLVMValueRef array_size = LLVMConstInt(LLVMInt32Type(),
+                                                   last*4 + 4, 0);
             bld->temps_array = lp_build_array_alloca(bld->base.builder,
-                                                     vec_type, val, "");
+                                                     vec_type, array_size, "");
          } else {
             for (i = 0; i < NUM_CHANNELS; i++)
                bld->temps[idx][i] = lp_build_alloca(bld->base.builder,
@@ -939,7 +1000,8 @@ static boolean
 emit_instruction(
    struct lp_build_tgsi_soa_context *bld,
    const struct tgsi_full_instruction *inst,
-   const struct tgsi_opcode_info *info)
+   const struct tgsi_opcode_info *info,
+   int *pc)
 {
    unsigned chan_index;
    LLVMValueRef src0, src1, src2;
@@ -963,6 +1025,8 @@ emit_instruction(
     * redundant code.
     */
 
+   (*pc)++;
+
    assert(info->num_dst <= 1);
    if (info->num_dst) {
       FOR_EACH_DST0_ENABLED_CHANNEL( inst, chan_index ) {
@@ -1561,16 +1625,18 @@ emit_instruction(
       break;
 
    case TGSI_OPCODE_CAL:
-      /* FIXME */
-      return FALSE;
+      lp_exec_mask_call(&bld->exec_mask,
+                        inst->Label.Label,
+                        pc);
+
       break;
 
    case TGSI_OPCODE_RET:
-      /* FIXME */
-      return FALSE;
+      lp_exec_mask_ret(&bld->exec_mask, pc);
       break;
 
    case TGSI_OPCODE_END:
+      *pc = -1;
       break;
 
    case TGSI_OPCODE_SSG:
@@ -1736,6 +1802,10 @@ emit_instruction(
       lp_exec_bgnloop(&bld->exec_mask);
       break;
 
+   case TGSI_OPCODE_BGNSUB:
+      lp_exec_mask_bgnsub(&bld->exec_mask);
+      break;
+
    case TGSI_OPCODE_ELSE:
       lp_exec_mask_cond_invert(&bld->exec_mask);
       break;
@@ -1748,6 +1818,10 @@ emit_instruction(
       lp_exec_endloop(&bld->exec_mask);
       break;
 
+   case TGSI_OPCODE_ENDSUB:
+      lp_exec_mask_endsub(&bld->exec_mask, pc);
+      break;
+
    case TGSI_OPCODE_PUSHA:
       /* deprecated? */
       assert(0);
@@ -1888,7 +1962,9 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
    struct lp_build_tgsi_soa_context bld;
    struct tgsi_parse_context parse;
    uint num_immediates = 0;
+   uint num_instructions = 0;
    unsigned i;
+   int pc = 0;
 
    /* Setup build context */
    memset(&bld, 0, sizeof bld);
@@ -1902,6 +1978,13 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
    bld.sampler = sampler;
    bld.has_indirect_addressing = info->opcode_count[TGSI_OPCODE_ARR] > 0 ||
                                  info->opcode_count[TGSI_OPCODE_ARL] > 0;
+   bld.instructions = (struct tgsi_full_instruction *)
+                      MALLOC( LP_MAX_INSTRUCTIONS * sizeof(struct tgsi_full_instruction) );
+   bld.max_instructions = LP_MAX_INSTRUCTIONS;
+
+   if (!bld.instructions) {
+      return;
+   }
 
    lp_exec_mask_init(&bld.exec_mask, &bld.base);
 
@@ -1918,11 +2001,21 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
 
       case TGSI_TOKEN_TYPE_INSTRUCTION:
          {
-            unsigned opcode = parse.FullToken.FullInstruction.Instruction.Opcode;
-            const struct tgsi_opcode_info *opcode_info = tgsi_get_opcode_info(opcode);
-            if (!emit_instruction( &bld, &parse.FullToken.FullInstruction, opcode_info ))
-               _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
-                             opcode_info->mnemonic);
+            /* save expanded instruction */
+            if (num_instructions == bld.max_instructions) {
+               bld.instructions = REALLOC(bld.instructions,
+                                          bld.max_instructions
+                                          * sizeof(struct tgsi_full_instruction),
+                                          (bld.max_instructions + LP_MAX_INSTRUCTIONS)
+                                          * sizeof(struct tgsi_full_instruction));
+               bld.max_instructions += LP_MAX_INSTRUCTIONS;
+            }
+
+            memcpy(bld.instructions + num_instructions,
+                   &parse.FullToken.FullInstruction,
+                   sizeof(bld.instructions[0]));
+
+            num_instructions++;
          }
 
          break;
@@ -1949,6 +2042,16 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
          assert( 0 );
       }
    }
+
+   while (pc != -1) {
+      struct tgsi_full_instruction *instr = bld.instructions + pc;
+      const struct tgsi_opcode_info *opcode_info =
+         tgsi_get_opcode_info(instr->Instruction.Opcode);
+      if (!emit_instruction( &bld, instr, opcode_info, &pc ))
+         _debug_printf("warning: failed to translate tgsi opcode %s to LLVM\n",
+                       opcode_info->mnemonic);
+   }
+
    if (0) {
       LLVMBasicBlockRef block = LLVMGetInsertBlock(builder);
       LLVMValueRef function = LLVMGetBasicBlockParent(block);
@@ -1958,5 +2061,14 @@ lp_build_tgsi_soa(LLVMBuilderRef builder,
       debug_printf("2222222222222222222222222222 \n");
    }
    tgsi_parse_free( &parse );
+
+   if (0) {
+      LLVMModuleRef module = LLVMGetGlobalParent(
+         LLVMGetBasicBlockParent(LLVMGetInsertBlock(bld.base.builder)));
+      LLVMDumpModule(module);
+
+   }
+
+   FREE( bld.instructions );
 }
 
index 37d278d23797a51e98770257f0967f5a73cf0b1f..aac3a57bc73383945241fcdb3a844d297e6af6ac 100644 (file)
@@ -195,6 +195,7 @@ lp_uint_type(struct lp_type type)
 {
    struct lp_type res_type;
 
+   assert(type.length <= LP_MAX_VECTOR_LENGTH);
    memset(&res_type, 0, sizeof res_type);
    res_type.width = type.width;
    res_type.length = type.length;
@@ -211,6 +212,7 @@ lp_int_type(struct lp_type type)
 {
    struct lp_type res_type;
 
+   assert(type.length <= LP_MAX_VECTOR_LENGTH);
    memset(&res_type, 0, sizeof res_type);
    res_type.width = type.width;
    res_type.length = type.length;
@@ -238,6 +240,43 @@ lp_wider_type(struct lp_type type)
 }
 
 
+/**
+ * Return the size of the LLVMType in bits.
+ * XXX this function doesn't necessarily handle all LLVM types.
+ */
+unsigned
+lp_sizeof_llvm_type(LLVMTypeRef t)
+{
+   LLVMTypeKind k = LLVMGetTypeKind(t);
+
+   switch (k) {
+   case LLVMIntegerTypeKind:
+      return LLVMGetIntTypeWidth(t);
+   case LLVMFloatTypeKind:
+      return 8 * sizeof(float);
+   case LLVMDoubleTypeKind:
+      return 8 * sizeof(double);
+   case LLVMVectorTypeKind:
+      {
+         LLVMTypeRef elem = LLVMGetElementType(t);
+         unsigned len = LLVMGetVectorSize(t);
+         return len * lp_sizeof_llvm_type(elem);
+      }
+      break;
+   case LLVMArrayTypeKind:
+      {
+         LLVMTypeRef elem = LLVMGetElementType(t);
+         unsigned len = LLVMGetArrayLength(t);
+         return len * lp_sizeof_llvm_type(elem);
+      }
+      break;
+   default:
+      assert(0 && "Unexpected type in lp_get_llvm_type_size()");
+      return 0;
+   }
+}
+
+
 /**
  * Return string name for a LLVMTypeKind.  Useful for debugging.
  */
@@ -315,6 +354,11 @@ lp_dump_llvmtype(LLVMTypeRef t)
       unsigned b = LLVMGetIntTypeWidth(t);
       debug_printf("%u-bit Integer\n", b);
    }
+   else if (k == LLVMPointerTypeKind) {
+      LLVMTypeRef te = LLVMGetElementType(t);
+      debug_printf("Pointer to ");
+      lp_dump_llvmtype(te);
+   }
    else {
       debug_printf("%s\n", lp_typekind_name(k));
    }
index b3f9e9175d39234502213942ebe46a70c51f1196..17819d4d32a3ab1d144539fbb000f63fc4a9984f 100644 (file)
@@ -316,6 +316,10 @@ struct lp_type
 lp_wider_type(struct lp_type type);
 
 
+unsigned
+lp_sizeof_llvm_type(LLVMTypeRef t);
+
+
 const char *
 lp_typekind_name(LLVMTypeKind t);
 
index 1218242653faf3d95007f8cd38e3a60884e97de0..c15d970b573a2055328682f40a477ae28ba5f87a 100644 (file)
@@ -3136,7 +3136,7 @@ exec_instruction(
       break;
 
    case TGSI_OPCODE_DIV:
-      assert( 0 );
+      exec_vector_binary(mach, inst, micro_div, TGSI_EXEC_DATA_FLOAT, TGSI_EXEC_DATA_FLOAT);
       break;
 
    case TGSI_OPCODE_DP2:
index ad553c71a5703acdfe49e690d781dffa971a4fed..3521847b61901e40593e219f1dbcf4dd7a1c70de 100644 (file)
@@ -1366,4 +1366,12 @@ tgsi_emit_ppc(const struct tgsi_token *tokens,
    return ok;
 }
 
+#else
+
+void ppc_dummy_func(void);
+
+void ppc_dummy_func(void)
+{
+}
+
 #endif /* PIPE_ARCH_PPC */
index 417d0cf04c924350ed37dfc4d792d010fb9f7cb8..6e250575d66756592a7cfc03aca502724e1685a6 100644 (file)
@@ -67,21 +67,6 @@ BOOL WINAPI j_SymInitialize(HANDLE hProcess, PSTR UserSearchPath, BOOL fInvadePr
       return FALSE;
 }
 
-typedef BOOL (WINAPI *PFNSYMCLEANUP)(HANDLE);
-static PFNSYMCLEANUP pfnSymCleanup = NULL;
-
-static
-BOOL WINAPI j_SymCleanup(HANDLE hProcess)
-{
-   if(
-      (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
-      (pfnSymCleanup || (pfnSymCleanup = (PFNSYMCLEANUP) GetProcAddress(hModule_Imagehlp, "SymCleanup")))
-   )
-      return pfnSymCleanup(hProcess);
-   else
-      return FALSE;
-}
-
 typedef DWORD (WINAPI *PFNSYMSETOPTIONS)(DWORD);
 static PFNSYMSETOPTIONS pfnSymSetOptions = NULL;
 
@@ -97,36 +82,6 @@ DWORD WINAPI j_SymSetOptions(DWORD SymOptions)
       return FALSE;
 }
 
-typedef BOOL (WINAPI *PFNSYMUNDNAME)(PIMAGEHLP_SYMBOL, PSTR, DWORD);
-static PFNSYMUNDNAME pfnSymUnDName = NULL;
-
-static
-BOOL WINAPI j_SymUnDName(PIMAGEHLP_SYMBOL Symbol, PSTR UnDecName, DWORD UnDecNameLength)
-{
-   if(
-      (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
-      (pfnSymUnDName || (pfnSymUnDName = (PFNSYMUNDNAME) GetProcAddress(hModule_Imagehlp, "SymUnDName")))
-   )
-      return pfnSymUnDName(Symbol, UnDecName, UnDecNameLength);
-   else
-      return FALSE;
-}
-
-typedef PFUNCTION_TABLE_ACCESS_ROUTINE PFNSYMFUNCTIONTABLEACCESS;
-static PFNSYMFUNCTIONTABLEACCESS pfnSymFunctionTableAccess = NULL;
-
-static
-PVOID WINAPI j_SymFunctionTableAccess(HANDLE hProcess, DWORD AddrBase)
-{
-   if(
-      (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
-      (pfnSymFunctionTableAccess || (pfnSymFunctionTableAccess = (PFNSYMFUNCTIONTABLEACCESS) GetProcAddress(hModule_Imagehlp, "SymFunctionTableAccess")))
-   )
-      return pfnSymFunctionTableAccess(hProcess, AddrBase);
-   else
-      return NULL;
-}
-
 typedef PGET_MODULE_BASE_ROUTINE PFNSYMGETMODULEBASE;
 static PFNSYMGETMODULEBASE pfnSymGetModuleBase = NULL;
 
@@ -142,41 +97,6 @@ DWORD WINAPI j_SymGetModuleBase(HANDLE hProcess, DWORD dwAddr)
       return 0;
 }
 
-typedef BOOL (WINAPI *PFNSTACKWALK)(DWORD, HANDLE, HANDLE, LPSTACKFRAME, LPVOID, PREAD_PROCESS_MEMORY_ROUTINE, PFUNCTION_TABLE_ACCESS_ROUTINE, PGET_MODULE_BASE_ROUTINE, PTRANSLATE_ADDRESS_ROUTINE);
-static PFNSTACKWALK pfnStackWalk = NULL;
-
-static
-BOOL WINAPI j_StackWalk(
-   DWORD MachineType, 
-   HANDLE hProcess, 
-   HANDLE hThread, 
-   LPSTACKFRAME StackFrame, 
-   PVOID ContextRecord, 
-   PREAD_PROCESS_MEMORY_ROUTINE ReadMemoryRoutine,  
-   PFUNCTION_TABLE_ACCESS_ROUTINE FunctionTableAccessRoutine,
-   PGET_MODULE_BASE_ROUTINE GetModuleBaseRoutine, 
-   PTRANSLATE_ADDRESS_ROUTINE TranslateAddress 
-)
-{
-   if(
-      (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
-      (pfnStackWalk || (pfnStackWalk = (PFNSTACKWALK) GetProcAddress(hModule_Imagehlp, "StackWalk")))
-   )
-      return pfnStackWalk(
-         MachineType, 
-         hProcess, 
-         hThread, 
-         StackFrame, 
-         ContextRecord, 
-         ReadMemoryRoutine,  
-         FunctionTableAccessRoutine,
-         GetModuleBaseRoutine, 
-         TranslateAddress 
-      );
-   else
-      return FALSE;
-}
-
 typedef BOOL (WINAPI *PFNSYMGETSYMFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_SYMBOL);
 static PFNSYMGETSYMFROMADDR pfnSymGetSymFromAddr = NULL;
 
@@ -192,21 +112,6 @@ BOOL WINAPI j_SymGetSymFromAddr(HANDLE hProcess, DWORD Address, PDWORD Displacem
       return FALSE;
 }
 
-typedef BOOL (WINAPI *PFNSYMGETLINEFROMADDR)(HANDLE, DWORD, LPDWORD, PIMAGEHLP_LINE);
-static PFNSYMGETLINEFROMADDR pfnSymGetLineFromAddr = NULL;
-
-static
-BOOL WINAPI j_SymGetLineFromAddr(HANDLE hProcess, DWORD dwAddr, PDWORD pdwDisplacement, PIMAGEHLP_LINE Line)
-{
-   if(
-      (hModule_Imagehlp || (hModule_Imagehlp = LoadLibraryA("IMAGEHLP.DLL"))) &&
-      (pfnSymGetLineFromAddr || (pfnSymGetLineFromAddr = (PFNSYMGETLINEFROMADDR) GetProcAddress(hModule_Imagehlp, "SymGetLineFromAddr")))
-   )
-      return pfnSymGetLineFromAddr(hProcess, dwAddr, pdwDisplacement, Line);
-   else
-      return FALSE;
-}
-
 
 static INLINE boolean
 debug_symbol_print_imagehlp(const void *addr)
index 68a6da804e893879f8fe76aa5788a10857d87763..49536c0d593317a0be293d1cb7e68a3f31d222da 100644 (file)
@@ -70,6 +70,9 @@ util_dump_blend_factor(unsigned value, boolean shortened);
 const char *
 util_dump_blend_func(unsigned value, boolean shortened);
 
+const char *
+util_dump_logicop(unsigned value, boolean shortened);
+
 const char *
 util_dump_func(unsigned value, boolean shortened);
 
index c4ffc7ae35a9695c5763bd307fd737fec0d631a9..692d4447c66c4f143403f682a490a5010423b990 100644 (file)
@@ -159,6 +159,49 @@ util_dump_blend_func_short_names[] = {
 DEFINE_UTIL_DUMP_CONTINUOUS(blend_func)
 
 
+static const char *
+util_dump_logicop_names[] = {
+   "PIPE_LOGICOP_CLEAR",
+   "PIPE_LOGICOP_NOR",
+   "PIPE_LOGICOP_AND_INVERTED",
+   "PIPE_LOGICOP_COPY_INVERTED",
+   "PIPE_LOGICOP_AND_REVERSE",
+   "PIPE_LOGICOP_INVERT",
+   "PIPE_LOGICOP_XOR",
+   "PIPE_LOGICOP_NAND",
+   "PIPE_LOGICOP_AND",
+   "PIPE_LOGICOP_EQUIV",
+   "PIPE_LOGICOP_NOOP",
+   "PIPE_LOGICOP_OR_INVERTED",
+   "PIPE_LOGICOP_COPY",
+   "PIPE_LOGICOP_OR_REVERSE",
+   "PIPE_LOGICOP_OR",
+   "PIPE_LOGICOP_SET"
+};
+
+static const char *
+util_dump_logicop_short_names[] = {
+   "clear",
+   "nor",
+   "and_inverted",
+   "copy_inverted",
+   "and_reverse",
+   "invert",
+   "xor",
+   "nand",
+   "and",
+   "equiv",
+   "noop",
+   "or_inverted",
+   "copy",
+   "or_reverse",
+   "or",
+   "set"
+};
+
+DEFINE_UTIL_DUMP_CONTINUOUS(logicop)
+
+
 static const char *
 util_dump_func_names[] = {
    "PIPE_FUNC_NEVER",
@@ -215,6 +258,7 @@ DEFINE_UTIL_DUMP_CONTINUOUS(stencil_op)
 
 static const char *
 util_dump_tex_target_names[] = {
+   "PIPE_BUFFER",
    "PIPE_TEXTURE_1D",
    "PIPE_TEXTURE_2D",
    "PIPE_TEXTURE_3D",
@@ -223,6 +267,7 @@ util_dump_tex_target_names[] = {
 
 static const char *
 util_dump_tex_target_short_names[] = {
+   "buffer",
    "1d",
    "2d",
    "3d",
index 0c1bbc84c172a5dba89586dd06a74d7931b3eec3..6d0016c0ad8c60fc529d3fd6d8116e1ca5dc836d 100644 (file)
@@ -37,9 +37,6 @@
 '''
 
 
-import sys
-import math
-
 from u_format_parse import *
 
 
index 7076c676aaf000f50d0362e3865fab397d404d54..ddb9f2443d9b805fba7b9b78f77940c59fa230c0 100755 (executable)
@@ -43,7 +43,7 @@ ZS = 'zs'
 
 
 def is_pot(x):
-   return (x & (x - 1)) == 0;
+   return (x & (x - 1)) == 0
 
 
 VERY_LARGE = 99999999999999999999999
index a4c76dc00b3fdc0f51940dd31b11b3bc1b7ed943..3e8000f3687bd2f5145659b7325a3634a6f9b2e2 100644 (file)
@@ -39,7 +39,6 @@
 '''
 
 
-import sys
 import math
 
 
index 8007482e971ddab4359d04d8f1e5861c59b0cdfa..915cf3b9273951f68d3c1d39e39ef65c6fc3b818 100644 (file)
@@ -83,11 +83,11 @@ for i in xrange(1, 1024):
 
        # normalize number
        while (m & 0x00800000) == 0:
-               e -= 0x00800000;
-               m <<= 1;
+               e -= 0x00800000
+               m <<= 1
 
-       m &= ~0x00800000;
-       e += 0x38800000;
+       m &= ~0x00800000
+       e += 0x38800000
        value(m | e)
 
 # normals
index c82e681a254db3b40077f3ed59a810aa52553faf..ec358e34545c31b50a7526dada590b00829db88e 100644 (file)
@@ -200,9 +200,16 @@ returned).  Otherwise, if the ``wait`` parameter is FALSE, the call
 will not block and the return value will be TRUE if the query has
 completed or FALSE otherwise.
 
-A common type of query is the occlusion query which counts the number of
-fragments/pixels which are written to the framebuffer (and not culled by
-Z/stencil/alpha testing or shader KILL instructions).
+The most common type of query is the occlusion query,
+``PIPE_QUERY_OCCLUSION_COUNTER``, which counts the number of fragments which
+are written to the framebuffer without being culled by
+:ref:`Depth, Stencil, & Alpha` testing or shader KILL instructions.
+
+Another type of query, ``PIPE_QUERY_TIME_ELAPSED``, returns the amount of
+time, in nanoseconds, the context takes to perform operations.
+
+Gallium does not guarantee the availability of any query types; one must
+always check the capabilities of the :ref:`Screen` first.
 
 
 Conditional Rendering
@@ -284,11 +291,6 @@ data to be written to the resource at this point.
 The returned map points to the start of the mapped range according to
 the box region, not the beginning of the resource.
 
-.. _transfer_flush_region:
-``transfer_flush_region`` If a transfer was created with TRANFER_FLUSH_EXPLICIT,
-only the region specified is guaranteed to be written to. This is relative to
-the mapped range, not the beginning of the resource.
-
 ``transfer_unmap`` remove the memory mapping for the transfer object.
 Any pointers into the map should be considered invalid and discarded.
 
@@ -296,6 +298,16 @@ Any pointers into the map should be considered invalid and discarded.
 Basically get_transfer, transfer_map, data write, transfer_unmap, and
 transfer_destroy all in one.
 
+.. _transfer_flush_region:
+
+transfer_flush_region
+%%%%%%%%%%%%%%%%%%%%%
+
+If a transfer was created with ``FLUSH_EXPLICIT``, it will not automatically
+be flushed on write or unmap. Flushes must be requested with
+``transfer_flush_region``. Flush ranges are relative to the mapped range, not
+the beginning of the resource.
+
 .. _pipe_transfer:
 
 PIPE_TRANSFER
@@ -315,5 +327,4 @@ These flags control the behavior of a transfer object.
   operations pending on the resource are undefined. Cannot be used with
   ``READ``.
 * ``FLUSH_EXPLICIT``: Written ranges will be notified later with
-  :ref:`transfer_flush_region`. Cannot be used with
-  ``READ``.
+  :ref:`transfer_flush_region`. Cannot be used with ``READ``.
index 71b7aec35a5cc85755c8767b305d7bd682015d30..96257f93df9161b953fcb975964249ea03498876 100644 (file)
@@ -1,3 +1,5 @@
+.. _screen:
+
 Screen
 ======
 
@@ -33,6 +35,7 @@ The integer capabilities:
 * ``MAX_RENDER_TARGETS``: The maximum number of render targets that may be
   bound.
 * ``OCCLUSION_QUERY``: Whether occlusion queries are available.
+* ``TIMER_QUERY``: Whether timer queries are available.
 * ``TEXTURE_SHADOW_MAP``: XXX
 * ``MAX_TEXTURE_2D_LEVELS``: The maximum number of mipmap levels available
   for a 2D texture.
index 5af4eaa88b114d0998719ffd57aacf02ef4f1fd7..750f0aa98ab1add428d876fc9b2e8e4218bf24cd 100644 (file)
@@ -76,6 +76,8 @@ cell_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_OCCLUSION_QUERY:
       return 1;
+   case PIPE_CAP_TIMER_QUERY:
+      return 0;
    case PIPE_CAP_TEXTURE_SHADOW_MAP:
       return 10;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
index d196c779e43d391dc0d1540739914d021b8e145f..7cf627d975bfa15bd713604844e0796cd837397e 100644 (file)
@@ -113,6 +113,8 @@ i915_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_OCCLUSION_QUERY:
       return 0;
+   case PIPE_CAP_TIMER_QUERY:
+      return 0;
    case PIPE_CAP_TEXTURE_SHADOW_MAP:
       return 1;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
index 003b1fd5bf0f807be9fdc6bd8fe397587470152d..8b3f46f2c1632cf4b288d0e2ca4f6a1994464c8d 100644 (file)
@@ -161,7 +161,7 @@ brw_batchbuffer_emit_reloc(struct brw_batchbuffer *batch,
    int ret;
 
    if (batch->ptr - batch->map > batch->buf->size) {
-      debug_printf("bad relocation ptr %p map %p offset %d size %d\n",
+      debug_printf("bad relocation ptr %p map %p offset %li size %i\n",
                   batch->ptr, batch->map, batch->ptr - batch->map, batch->buf->size);
 
       return PIPE_ERROR_OUT_OF_MEMORY;
index 07537fe44efb07f2560cdf0af9de737321df1f65..ca09d88fd1203f6808bef8f6e9d0057207d91914 100644 (file)
@@ -210,7 +210,7 @@ brw_texture_get_handle(struct pipe_screen *screen,
 
    stride = tex->pitch * tex->cpp;
 
-   return bscreen->sws->bo_get_handle(tex->bo, whandle, stride);
+   return bscreen->sws->bo_get_handle(tex->bo, whandle, stride) == PIPE_OK;
 }
 
 
index d242691f2d2c884919d9be92e08dedc14a556cf0..1890b640e908469b47d108a71657e3217229e58a 100644 (file)
@@ -172,6 +172,8 @@ brw_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return 1;
    case PIPE_CAP_OCCLUSION_QUERY:
       return 0;
+   case PIPE_CAP_TIMER_QUERY:
+      return 0;
    case PIPE_CAP_TEXTURE_SHADOW_MAP:
       return 1;
    case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
index 4ea367597e18eb740dd856e50097511b4850a09e..526e85c82e11ffa0c39183527d7ee4c6d5183180 100644 (file)
@@ -59,7 +59,7 @@ lp_tile_soa.c: lp_tile_soa.py ../../auxiliary/util/u_format_parse.py ../../auxil
        python lp_tile_soa.py ../../auxiliary/util/u_format.csv > $@
 
 LDFLAGS += $(LLVM_LDFLAGS)
-LIBS += $(GL_LIB_DEPS) -L../../auxiliary/ -lgallium libllvmpipe.a $(LLVM_LIBS)
+LIBS += -L../../auxiliary/ -lgallium libllvmpipe.a $(LLVM_LIBS) $(GL_LIB_DEPS)
 LD=g++
 
 $(PROGS): lp_test_main.o libllvmpipe.a
index ee81814361020bceca873a86ad4286eba14100c9..92fb2b3ee5b530477999e211c19aac21a59998a9 100644 (file)
@@ -39,16 +39,13 @@ st_print_current(void);
 #define DEBUG_PIPE      0x1
 #define DEBUG_TGSI      0x2
 #define DEBUG_TEX       0x4
-#define DEBUG_ASM       0x8
 #define DEBUG_SETUP     0x10
 #define DEBUG_RAST      0x20
 #define DEBUG_QUERY     0x40
 #define DEBUG_SCREEN    0x80
-#define DEBUG_JIT       0x100
 #define DEBUG_SHOW_TILES    0x200
 #define DEBUG_SHOW_SUBTILES 0x400
 #define DEBUG_COUNTERS      0x800
-#define DEBUG_NO_LLVM_OPT  0x1000
 
 
 #ifdef DEBUG
index 243aea6c3a3c092eb7b8b9ef2f193d658699229b..23aa34ddec1c65d89aa0471816cb1ddcdd5a5346 100644 (file)
@@ -38,7 +38,7 @@
 #include "util/u_memory.h"
 #include "util/u_cpu_detect.h"
 #include "gallivm/lp_bld_init.h"
-#include "lp_debug.h"
+#include "gallivm/lp_bld_debug.h"
 #include "lp_screen.h"
 #include "gallivm/lp_bld_intr.h"
 #include "lp_jit.h"
@@ -151,8 +151,9 @@ lp_jit_init_globals(struct llvmpipe_screen *screen)
       screen->context_ptr_type = LLVMPointerType(context_type, 0);
    }
 
-   if (LP_DEBUG & DEBUG_JIT)
+   if (gallivm_debug & GALLIVM_DEBUG_IR) {
       LLVMDumpModule(screen->module);
+   }
 }
 
 
@@ -180,7 +181,7 @@ lp_jit_screen_init(struct llvmpipe_screen *screen)
    screen->pass = LLVMCreateFunctionPassManager(screen->provider);
    LLVMAddTargetData(screen->target, screen->pass);
 
-   if ((LP_DEBUG & DEBUG_NO_LLVM_OPT) == 0) {
+   if ((gallivm_debug & GALLIVM_DEBUG_NO_OPT) == 0) {
       /* These are the passes currently listed in llvm-c/Transforms/Scalar.h,
        * but there are more on SVN. */
       /* TODO: Add more passes */
index 9d254853cb862188acd7293b3b82f2bcc289363a..22fbf381ae0da8af5e2286fb095617523c8549b7 100644 (file)
@@ -53,16 +53,13 @@ static const struct debug_named_value lp_debug_flags[] = {
    { "pipe",   DEBUG_PIPE },
    { "tgsi",   DEBUG_TGSI },
    { "tex",    DEBUG_TEX },
-   { "asm",    DEBUG_ASM },
    { "setup",  DEBUG_SETUP },
    { "rast",   DEBUG_RAST },
    { "query",  DEBUG_QUERY },
    { "screen", DEBUG_SCREEN },
-   { "jit",    DEBUG_JIT },
    { "show_tiles",    DEBUG_SHOW_TILES },
    { "show_subtiles", DEBUG_SHOW_SUBTILES },
    { "counters", DEBUG_COUNTERS },
-   { "nopt", DEBUG_NO_LLVM_OPT },
    {NULL, 0}
 };
 #endif
@@ -108,6 +105,8 @@ llvmpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return PIPE_MAX_COLOR_BUFS;
    case PIPE_CAP_OCCLUSION_QUERY:
       return 1;
+   case PIPE_CAP_TIMER_QUERY:
+      return 0;
    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
       return 1;
    case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
index cc163ebd4fa987bbf788f578202228c639dc4732..9ef78e6badf61fa56462c9917f096041437f84d1 100644 (file)
@@ -87,7 +87,6 @@
 #include "lp_bld_depth.h"
 #include "lp_bld_interp.h"
 #include "lp_context.h"
-#include "lp_debug.h"
 #include "lp_perf.h"
 #include "lp_screen.h"
 #include "lp_setup.h"
@@ -862,7 +861,7 @@ generate_fragment(struct llvmpipe_context *lp,
    if (1)
       LLVMRunFunctionPassManager(screen->pass, function);
 
-   if (LP_DEBUG & DEBUG_JIT) {
+   if (gallivm_debug & GALLIVM_DEBUG_IR) {
       /* Print the LLVM IR to stderr */
       lp_debug_dump_value(function);
       debug_printf("\n");
@@ -876,12 +875,84 @@ generate_fragment(struct llvmpipe_context *lp,
 
       variant->jit_function[do_tri_test] = cast_voidptr_to_lp_jit_frag_func(f);
 
-      if (LP_DEBUG & DEBUG_ASM)
+      if (gallivm_debug & GALLIVM_DEBUG_ASM) {
          lp_disassemble(f);
+      }
    }
 }
 
 
+static void
+dump_fs_variant_key(const struct lp_fragment_shader_variant_key *key)
+{
+   unsigned i;
+
+   debug_printf("fs variant %p:\n", (void *) key);
+
+   if (key->depth.enabled) {
+      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);
+   }
+
+   for (i = 0; i < 2; ++i) {
+      if (key->stencil[i].enabled) {
+         debug_printf("stencil[%u].func = %s\n", i, util_dump_func(key->stencil[i].func, TRUE));
+         debug_printf("stencil[%u].fail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].fail_op, TRUE));
+         debug_printf("stencil[%u].zpass_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zpass_op, TRUE));
+         debug_printf("stencil[%u].zfail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zfail_op, TRUE));
+         debug_printf("stencil[%u].valuemask = 0x%x\n", i, key->stencil[i].valuemask);
+         debug_printf("stencil[%u].writemask = 0x%x\n", i, key->stencil[i].writemask);
+      }
+   }
+
+   if (key->alpha.enabled) {
+      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 = %s\n", util_dump_logicop(key->blend.logicop_func, TRUE));
+   }
+   else if (key->blend.rt[0].blend_enable) {
+      debug_printf("blend.rgb_func = %s\n",   util_dump_blend_func  (key->blend.rt[0].rgb_func, TRUE));
+      debug_printf("blend.rgb_src_factor = %s\n",   util_dump_blend_factor(key->blend.rt[0].rgb_src_factor, TRUE));
+      debug_printf("blend.rgb_dst_factor = %s\n",   util_dump_blend_factor(key->blend.rt[0].rgb_dst_factor, TRUE));
+      debug_printf("blend.alpha_func = %s\n",       util_dump_blend_func  (key->blend.rt[0].alpha_func, TRUE));
+      debug_printf("blend.alpha_src_factor = %s\n", util_dump_blend_factor(key->blend.rt[0].alpha_src_factor, TRUE));
+      debug_printf("blend.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",
+                      util_format_name(key->sampler[i].format));
+         debug_printf("  .target = %s\n",
+                      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",
+                      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",
+                      util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
+         debug_printf("  .min_mip_filter = %s\n",
+                      util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
+         debug_printf("  .mag_img_filter = %s\n",
+                      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", util_dump_func(key->sampler[i].compare_func, TRUE));
+         debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
+      }
+   }
+}
+
+
+
 static struct lp_fragment_shader_variant *
 generate_variant(struct llvmpipe_context *lp,
                  struct lp_fragment_shader *shader,
@@ -889,67 +960,9 @@ generate_variant(struct llvmpipe_context *lp,
 {
    struct lp_fragment_shader_variant *variant;
 
-   if (LP_DEBUG & DEBUG_JIT) {
-      unsigned i;
-
+   if (gallivm_debug & GALLIVM_DEBUG_IR) {
       tgsi_dump(shader->base.tokens, 0);
-      if(key->depth.enabled) {
-         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);
-      }
-      for (i = 0; i < 2; ++i) {
-         if(key->stencil[i].enabled) {
-            debug_printf("stencil[%u].func = %s\n", i, util_dump_func(key->stencil[i].func, TRUE));
-            debug_printf("stencil[%u].fail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].fail_op, TRUE));
-            debug_printf("stencil[%u].zpass_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zpass_op, TRUE));
-            debug_printf("stencil[%u].zfail_op = %s\n", i, util_dump_stencil_op(key->stencil[i].zfail_op, TRUE));
-            debug_printf("stencil[%u].valuemask = 0x%x\n", i, key->stencil[i].valuemask);
-            debug_printf("stencil[%u].writemask = 0x%x\n", i, key->stencil[i].writemask);
-         }
-      }
-      if(key->alpha.enabled) {
-         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",   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",
-                         util_format_name(key->sampler[i].format));
-            debug_printf("  .target = %s\n",
-                         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",
-                         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",
-                         util_dump_tex_filter(key->sampler[i].min_img_filter, TRUE));
-            debug_printf("  .min_mip_filter = %s\n",
-                         util_dump_tex_mipfilter(key->sampler[i].min_mip_filter, TRUE));
-            debug_printf("  .mag_img_filter = %s\n",
-                         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", util_dump_func(key->sampler[i].compare_func, TRUE));
-            debug_printf("  .normalized_coords = %u\n", key->sampler[i].normalized_coords);
-         }
-      }
+      dump_fs_variant_key(key);
    }
 
    variant = CALLOC_STRUCT(lp_fragment_shader_variant);
@@ -997,7 +1010,7 @@ llvmpipe_create_fs_state(struct pipe_context *pipe,
    /* we need to keep a local copy of the tokens */
    shader->base.tokens = tgsi_dup_tokens(templ->tokens);
 
-   if (LP_DEBUG & DEBUG_TGSI) {
+   if (gallivm_debug & GALLIVM_DEBUG_TGSI) {
       debug_printf("llvmpipe: Create fragment shader %p:\n", (void *) shader);
       tgsi_dump(templ->tokens, 0);
    }
index 0156ff95ff943f75a45e443147d9ff3a4f3ebdf5..97f938e6980e4af80fe442b46500f5f91087747e 100644 (file)
@@ -4208,9 +4208,12 @@ static void
 nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
 {
        struct nouveau_channel *chan = nv50->screen->base.channel;
+       struct nouveau_grobj *tesla = nv50->screen->tesla;
        struct nv50_program_exec *e;
        uint32_t *up, i;
        boolean upload = FALSE;
+       unsigned offset;
+       int width;
 
        if (!p->bo) {
                nouveau_bo_new(chan->device, NOUVEAU_BO_VRAM, 0x100,
@@ -4267,10 +4270,22 @@ nv50_program_validate_code(struct nv50_context *nv50, struct nv50_program *p)
                        NOUVEAU_ERR("0x%08x\n", e->inst[1]);
        }
 #endif
-       nv50_upload_sifc(nv50, p->bo, 0, NOUVEAU_BO_VRAM,
-                        NV50_2D_DST_FORMAT_R8_UNORM, 65536, 1, 262144,
-                        up, NV50_2D_SIFC_FORMAT_R8_UNORM, 0,
-                        0, 0, p->exec_size * 4, 1, 1);
+
+       /* SIFC_HEIGHT/SIFC_WIDTH of 65536 do not work, and are not reported
+        * as data error either. hw bug ? */
+#define SIFC_MAX_WIDTH (65536 - 256)
+       offset = 0;
+       width = p->exec_size * 4;
+       while (width > 0) {
+               nv50_upload_sifc(nv50, p->bo, offset, NOUVEAU_BO_VRAM,
+                                NV50_2D_DST_FORMAT_R8_UNORM, 65536, 1, 262144,
+                                &up[offset / 4], NV50_2D_SIFC_FORMAT_R8_UNORM,
+                                0, 0, 0, MIN2(SIFC_MAX_WIDTH, width), 1, 1);
+               width -= SIFC_MAX_WIDTH;
+               offset += SIFC_MAX_WIDTH;
+       }
+       BEGIN_RING(chan, tesla, NV50TCL_CODE_CB_FLUSH, 1);
+       OUT_RING  (chan, 0);
 
        FREE(up);
 }
index 244242b84342e200dbcd0db0dc8f05759b0b718a..c3ac804146267a08eb75a6cdbc6aaec07fb9dad2 100644 (file)
@@ -108,7 +108,7 @@ emit_vertex(struct push_context *ctx, unsigned n)
    int i;
 
    if (ctx->edgeflag_attr < 16) {
-      float *edgeflag = ctx->attr[ctx->edgeflag_attr].map +
+      float *edgeflag = (uint8_t *)ctx->attr[ctx->edgeflag_attr].map +
                         ctx->attr[ctx->edgeflag_attr].stride * n;
 
       if (*edgeflag != ctx->edgeflag) {
@@ -120,7 +120,8 @@ emit_vertex(struct push_context *ctx, unsigned n)
 
    BEGIN_RING_NI(chan, tesla, NV50TCL_VERTEX_DATA, ctx->vtx_size);
    for (i = 0; i < ctx->attr_nr; i++)
-      ctx->attr[i].push(chan, ctx->attr[i].map + ctx->attr[i].stride * n);
+      ctx->attr[i].push(chan,
+                       (uint8_t *)ctx->attr[i].map + ctx->attr[i].stride * n);
 }
 
 static void
@@ -243,14 +244,14 @@ nv50_push_elements_instanced(struct pipe_context *pipe,
          assert(bo->map);
          return;
       }
-      ctx.attr[n].map = bo->map + vb->buffer_offset + ve->src_offset;
+      ctx.attr[n].map = (uint8_t *)bo->map + vb->buffer_offset + ve->src_offset;
       nouveau_bo_unmap(bo);
 
       ctx.attr[n].stride = vb->stride;
       ctx.attr[n].divisor = ve->instance_divisor;
       if (ctx.attr[n].divisor) {
          ctx.attr[n].step = i_start % ve->instance_divisor;
-         ctx.attr[n].map += i_start * vb->stride;
+         ctx.attr[n].map = (uint8_t *)ctx.attr[n].map + i_start * vb->stride;
       }
 
       size = util_format_get_component_bits(ve->src_format,
@@ -331,7 +332,7 @@ nv50_push_elements_instanced(struct pipe_context *pipe,
               ctx.attr[i].divisor != ++ctx.attr[i].step)
             continue;
          ctx.attr[i].step = 0;
-         ctx.attr[i].map += ctx.attr[i].stride;
+         ctx.attr[i].map = (uint8_t *)ctx.attr[i].map + ctx.attr[i].stride;
       }
 
       u_split_prim_init(&s, mode, start, count);
index ff3a7b2843dbee8cb4b51c8baef0b0117e0bf180..757f13b640a6d429d29024fcc1e7cde479bab8d5 100644 (file)
@@ -125,6 +125,8 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
                return 8;
        case PIPE_CAP_OCCLUSION_QUERY:
                return 1;
+        case PIPE_CAP_TIMER_QUERY:
+               return 0;
        case PIPE_CAP_TEXTURE_SHADOW_MAP:
                return 1;
        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
@@ -150,6 +152,34 @@ nv50_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
        case PIPE_CAP_TGSI_FS_COORD_ORIGIN_LOWER_LEFT:
        case PIPE_CAP_TGSI_FS_COORD_PIXEL_CENTER_INTEGER:
                return 0;
+       case PIPE_CAP_MAX_VS_INSTRUCTIONS:
+       case PIPE_CAP_MAX_FS_INSTRUCTIONS:
+       case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
+       case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
+       case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
+       case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
+       case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
+       case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS: /* arbitrary limit */
+               return 16384;
+       case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
+       case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH: /* need stack bo */
+               return 4;
+       case PIPE_CAP_MAX_VS_INPUTS:
+               return 16;
+       case PIPE_CAP_MAX_FS_INPUTS: /* 128 / 4 with GP */
+               return 64 / 4;
+       case PIPE_CAP_MAX_VS_CONSTS:
+       case PIPE_CAP_MAX_FS_CONSTS:
+               return 65536 / 16;
+       case PIPE_CAP_MAX_VS_ADDRS:
+       case PIPE_CAP_MAX_FS_ADDRS: /* no spilling atm */
+               return 1;
+       case PIPE_CAP_MAX_VS_PREDS:
+       case PIPE_CAP_MAX_FS_PREDS: /* not yet handled */
+               return 0;
+       case PIPE_CAP_MAX_VS_TEMPS:
+       case PIPE_CAP_MAX_FS_TEMPS: /* no spilling atm */
+               return 128 / 4;
        default:
                NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
                return 0;
index c5581a6f9d080e1034b71f7373351481efcf84d6..f973cf24b9863c49bc1cffdeaadfa0a1b02a8921 100644 (file)
@@ -274,7 +274,6 @@ nv50_upload_sifc(struct nv50_context *nv50,
 {
        struct nouveau_channel *chan = nv50->screen->base.channel;
        struct nouveau_grobj *eng2d = nv50->screen->eng2d;
-       struct nouveau_grobj *tesla = nv50->screen->tesla;
        unsigned line_dwords = (w * cpp + 3) / 4;
 
        reloc |= NOUVEAU_BO_WR;
@@ -346,7 +345,4 @@ nv50_upload_sifc(struct nv50_context *nv50,
 
                src = (uint8_t *) src + src_pitch;
        }
-
-       BEGIN_RING(chan, tesla, NV50TCL_CODE_CB_FLUSH, 1);
-       OUT_RING  (chan, 0);
 }
index 0ff25e54f73ddcb014d45847159918abfa19d542..a44f9e94d7089ba78bb85a17116d92ed3928317d 100644 (file)
@@ -52,6 +52,8 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap param)
                return screen->is_nv4x ? 4 : 2;
        case PIPE_CAP_OCCLUSION_QUERY:
                return 1;
+        case PIPE_CAP_TIMER_QUERY:
+               return 0;
        case PIPE_CAP_TEXTURE_SHADOW_MAP:
                return 1;
        case PIPE_CAP_MAX_TEXTURE_2D_LEVELS:
@@ -84,6 +86,44 @@ nvfx_screen_get_param(struct pipe_screen *pscreen, enum pipe_cap 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_FS_INSTRUCTIONS:
+       case PIPE_CAP_MAX_FS_ALU_INSTRUCTIONS:
+       case PIPE_CAP_MAX_FS_TEX_INSTRUCTIONS:
+       case PIPE_CAP_MAX_FS_TEX_INDIRECTIONS:
+               return 4096;
+       case PIPE_CAP_MAX_FS_CONTROL_FLOW_DEPTH:
+               /* FIXME: is it the dynamic (nv30:0/nv40:24) or the static
+                  value (written there) ? */
+               return screen->is_nv4x ? 4 : 0;
+       /*case PIPE_CAP_MAX_FS_INPUTS:*/        /* FIXME */
+       /*case PIPE_CAP_MAX_FS_CONSTS:*/        /* FIXME */
+       /*      return 0;*/
+       case PIPE_CAP_MAX_FS_TEMPS:
+               return 32;
+       case PIPE_CAP_MAX_FS_ADDRS:
+               return screen->is_nv4x ? 1 : 0;
+       /*case PIPE_CAP_MAX_FS_PREDS:*/         /* FIXME */
+       /*      return 0;*/
+       case PIPE_CAP_MAX_VS_INSTRUCTIONS:
+       case PIPE_CAP_MAX_VS_ALU_INSTRUCTIONS:
+               return screen->is_nv4x ? 512 : 256;
+       case PIPE_CAP_MAX_VS_TEX_INSTRUCTIONS:
+       case PIPE_CAP_MAX_VS_TEX_INDIRECTIONS:
+               return screen->is_nv4x ? 512 : 0;
+       case PIPE_CAP_MAX_VS_CONTROL_FLOW_DEPTH:
+               /* FIXME: is it the dynamic (nv30/nv40:24) or the static
+                  value (written there) ? */
+               return screen->is_nv4x ? 4 : 1;
+       /*case PIPE_CAP_MAX_VS_INPUTS:*/        /* FIXME */
+       /*      return 0;*/
+       case PIPE_CAP_MAX_VS_CONSTS:
+               return 256;
+       case PIPE_CAP_MAX_VS_TEMPS:
+               return screen->is_nv4x ? 48 : 16;
+       case PIPE_CAP_MAX_VS_ADDRS:
+               return 2;
+       /*case PIPE_CAP_MAX_VS_PREDS:*/ /* FIXME */
+       /*      return 0;*/
        default:
                NOUVEAU_ERR("Unknown PIPE_CAP %d\n", param);
                return 0;
index 0444fdac7d5096f1885eb1d7eab681c09439604a..9837deaa5e31b6a3a134403516b4b5b82ef651a8 100644 (file)
@@ -80,6 +80,9 @@ static void r300_destroy_context(struct pipe_context* context)
     FREE(r300->ztop_state.state);
     FREE(r300->fs_constants.state);
     FREE(r300->vs_constants.state);
+    if (!r300->screen->caps.has_tcl) {
+        FREE(r300->vertex_stream_state.state);
+    }
     FREE(r300);
 }
 
@@ -151,6 +154,16 @@ static void r300_setup_atoms(struct r300_context* r300)
     r300->ztop_state.state = CALLOC_STRUCT(r300_ztop_state);
     r300->fs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
     r300->vs_constants.state = CALLOC_STRUCT(r300_constant_buffer);
+    if (!r300->screen->caps.has_tcl) {
+        r300->vertex_stream_state.state = CALLOC_STRUCT(r300_vertex_stream_state);
+    }
+
+    /* Some non-CSO atoms don't use the state pointer. */
+    r300->invariant_state.allow_null_state = TRUE;
+    r300->fs_rc_constant_state.allow_null_state = TRUE;
+    r300->pvs_flush.allow_null_state = TRUE;
+    r300->query_start.allow_null_state = TRUE;
+    r300->texture_cache_inval.allow_null_state = TRUE;
 }
 
 struct pipe_context* r300_create_context(struct pipe_screen* screen,
@@ -201,6 +214,9 @@ struct pipe_context* r300_create_context(struct pipe_screen* screen,
         draw_set_rasterize_stage(r300->draw, r300_draw_stage(r300));
         /* Enable Draw's clipping. */
         draw_set_driver_clipping(r300->draw, FALSE);
+        /* Disable converting points/lines to triangles. */
+        draw_wide_line_threshold(r300->draw, 10000000.f);
+        draw_wide_point_threshold(r300->draw, 10000000.f);
     }
 
     r300_setup_atoms(r300);
index 5ad448978b9d572efe04127de030a397ec5ecff8..e44906d00997c85d777ec28637496e29c1cf61a9 100644 (file)
@@ -55,6 +55,8 @@ struct r300_atom {
     unsigned size;
     /* Whether this atom should be emitted. */
     boolean dirty;
+    /* Whether this atom may be emitted with state == NULL. */
+    boolean allow_null_state;
 };
 
 struct r300_blend_state {
@@ -88,8 +90,10 @@ struct r300_dsa_state {
 };
 
 struct r300_rs_state {
-    /* Draw-specific rasterizer state */
+    /* Original rasterizer state. */
     struct pipe_rasterizer_state rs;
+    /* Draw-specific rasterizer state. */
+    struct pipe_rasterizer_state rs_draw;
 
     uint32_t vap_control_status;    /* R300_VAP_CNTL_STATUS: 0x2140 */
     uint32_t antialiasing_config;   /* R300_GB_AA_CONFIG: 0x4020 */
@@ -235,10 +239,6 @@ struct r300_constant_buffer {
 struct r300_query {
     /* The kind of query. Currently only OQ is supported. */
     unsigned type;
-    /* Whether this query is currently active. Only active queries will
-     * get emitted into the command stream, and only active queries get
-     * tallied. */
-    boolean active;
     /* The current count of this query. Required to be at least 32 bits. */
     unsigned int count;
     /* The offset of this query into the query buffer, in bytes. */
@@ -304,16 +304,6 @@ struct r300_texture {
     enum r300_buffer_tiling microtile, macrotile;
 };
 
-struct r300_vertex_info {
-    /* Parent class */
-    struct vertex_info vinfo;
-
-    /* R300_VAP_PROG_STREAK_CNTL_[0-7] */
-    uint32_t vap_prog_stream_cntl[8];
-    /* R300_VAP_PROG_STREAK_CNTL_EXT_[0-7] */
-    uint32_t vap_prog_stream_cntl_ext[8];
-};
-
 struct r300_vertex_element_state {
     unsigned count;
     struct pipe_vertex_element velem[PIPE_MAX_ATTRIBS];
index 8eb321fa08a352e9007ec7082d98b9c96fd40d0e..85a1aa7b06ebea4afbc977630cf71fb7d540b5a5 100644 (file)
@@ -40,6 +40,7 @@ static struct debug_option debug_options[] = {
     { "texalloc", DBG_TEXALLOC, "Texture allocation (for debugging)" },
     { "fall", DBG_FALL, "Fallbacks (for debugging)" },
     { "rs", DBG_RS, "Rasterizer (for debugging)" },
+    { "fb", DBG_FB, "Framebuffer (for debugging)" },
     { "anisohq", DBG_ANISOHQ, "High quality anisotropic filtering (for benchmarking)" },
     { "notiling", DBG_NO_TILING, "Disable tiling (for benchmarking)" },
     { "noimmd", DBG_NO_IMMD, "Disable immediate mode (for benchmarking)" },
@@ -97,3 +98,84 @@ void r300_init_debug(struct r300_screen * screen)
         }
     }
 }
+
+void r500_dump_rs_block(struct r300_rs_block *rs)
+{
+    unsigned count, ip, it_count, ic_count, i, j;
+    unsigned tex_ptr;
+    unsigned col_ptr, col_fmt;
+
+    count = rs->inst_count & 0xf;
+    count++;
+
+    it_count = rs->count & 0x7f;
+    ic_count = (rs->count >> 7) & 0xf;
+
+    fprintf(stderr, "RS Block: %d texcoords (linear), %d colors (perspective)\n",
+        it_count, ic_count);
+    fprintf(stderr, "%d instructions\n", count);
+
+    for (i = 0; i < count; i++) {
+        if (rs->inst[i] & 0x10) {
+            ip = rs->inst[i] & 0xf;
+            fprintf(stderr, "texture: ip %d to psf %d\n",
+                ip, (rs->inst[i] >> 5) & 0x7f);
+
+            tex_ptr = rs->ip[ip] & 0xffffff;
+            fprintf(stderr, "       : ");
+
+            j = 3;
+            do {
+                if (tex_ptr & 0x3f == 63) {
+                    fprintf(stderr, "1.0");
+                } else if (tex_ptr & 0x3f == 62) {
+                    fprintf(stderr, "0.0");
+                } else {
+                    fprintf(stderr, "[%d]", tex_ptr & 0x3f);
+                }
+            } while (j-- && fprintf(stderr, "/"));
+            fprintf(stderr, "\n");
+        }
+
+        if (rs->inst[i] & 0x10000) {
+            ip = (rs->inst[i] >> 12) & 0xf;
+            fprintf(stderr, "color: ip %d to psf %d\n",
+                ip, (rs->inst[i] >> 18) & 0x7f);
+
+            col_ptr = (rs->ip[ip] >> 24) & 0x7;
+            col_fmt = (rs->ip[ip] >> 27) & 0xf;
+            fprintf(stderr, "     : offset %d ", col_ptr);
+
+            switch (col_fmt) {
+                case 0:
+                    fprintf(stderr, "(R/G/B/A)");
+                    break;
+                case 1:
+                    fprintf(stderr, "(R/G/B/0)");
+                    break;
+                case 2:
+                    fprintf(stderr, "(R/G/B/1)");
+                    break;
+                case 4:
+                    fprintf(stderr, "(0/0/0/A)");
+                    break;
+                case 5:
+                    fprintf(stderr, "(0/0/0/0)");
+                    break;
+                case 6:
+                    fprintf(stderr, "(0/0/0/1)");
+                    break;
+                case 8:
+                    fprintf(stderr, "(1/1/1/A)");
+                    break;
+                case 9:
+                    fprintf(stderr, "(1/1/1/0)");
+                    break;
+                case 10:
+                    fprintf(stderr, "(1/1/1/1)");
+                    break;
+            }
+            fprintf(stderr, "\n");
+        }
+    }
+}
index 568109cf9604eadf96959b6899507ddfd3de1d7f..7f7f2929cc3ae8a008de86f9564b86ef5b4d106c 100644 (file)
@@ -548,8 +548,8 @@ void r300_emit_query_start(struct r300_context *r300, unsigned size, void*state)
 }
 
 
-static void r300_emit_query_finish(struct r300_context *r300,
-                                   struct r300_query *query)
+static void r300_emit_query_end_frag_pipes(struct r300_context *r300,
+                                           struct r300_query *query)
 {
     struct r300_capabilities* caps = &r300->screen->caps;
     CS_LOCALS(r300);
@@ -604,8 +604,8 @@ static void r300_emit_query_finish(struct r300_context *r300,
     END_CS;
 }
 
-static void rv530_emit_query_single(struct r300_context *r300,
-                                    struct r300_query *query)
+static void rv530_emit_query_end_single_z(struct r300_context *r300,
+                                          struct r300_query *query)
 {
     CS_LOCALS(r300);
 
@@ -617,8 +617,8 @@ static void rv530_emit_query_single(struct r300_context *r300,
     END_CS;
 }
 
-static void rv530_emit_query_double(struct r300_context *r300,
-                                    struct r300_query *query)
+static void rv530_emit_query_end_double_z(struct r300_context *r300,
+                                          struct r300_query *query)
 {
     CS_LOCALS(r300);
 
@@ -646,11 +646,13 @@ void r300_emit_query_end(struct r300_context* r300)
 
     if (caps->family == CHIP_FAMILY_RV530) {
         if (caps->num_z_pipes == 2)
-            rv530_emit_query_double(r300, query);
+            rv530_emit_query_end_double_z(r300, query);
         else
-            rv530_emit_query_single(r300, query);
+            rv530_emit_query_end_single_z(r300, query);
     } else 
-        r300_emit_query_finish(r300, query);
+        r300_emit_query_end_frag_pipes(r300, query);
+
+    query->begin_emitted = FALSE;
 }
 
 void r300_emit_rs_state(struct r300_context* r300, unsigned size, void* state)
@@ -714,6 +716,10 @@ void r300_emit_rs_block_state(struct r300_context* r300,
     unsigned count = (rs->inst_count & R300_RS_INST_COUNT_MASK) + 1;
     CS_LOCALS(r300);
 
+    if (SCREEN_DBG_ON(r300->screen, DBG_DRAW)) {
+        r500_dump_rs_block(rs);
+    }
+
     DBG(r300, DBG_DRAW, "r300: RS emit:\n");
 
     BEGIN_CS(size);
@@ -1094,7 +1100,8 @@ validate:
         }
     }
     /* ...occlusion query buffer... */
-    if (r300->query_start.dirty) {
+    if (r300->query_start.dirty ||
+        (r300->query_current && r300->query_current->begin_emitted)) {
         if (!r300_add_buffer(r300->rws, r300->oqbo,
                             0, RADEON_GEM_DOMAIN_GTT)) {
             r300->context.flush(&r300->context, 0, NULL);
index e78c6a3624f5c2a08f112445ab7a5352a770182c..d6876c1903f4b65ad66afc9d16737567e23b3d56 100644 (file)
@@ -1,5 +1,6 @@
 /*
  * Copyright 2008 Corbin Simpson <MostAwesomeDude@gmail.com>
+ * Copyright 2010 Marek Olšák <maraeo@gmail.com>
  *
  * Permission is hereby granted, free of charge, to any person obtaining a
  * copy of this software and associated documentation files (the "Software"),
@@ -37,6 +38,8 @@ static void r300_flush(struct pipe_context* pipe,
     struct r300_context *r300 = r300_context(pipe);
     struct r300_query *query;
     struct r300_atom *atom;
+    struct pipe_framebuffer_state *fb;
+    unsigned i;
 
     CS_LOCALS(r300);
     (void) cs_count;
@@ -48,15 +51,15 @@ static void r300_flush(struct pipe_context* pipe,
         draw_flush(r300->draw);
     }
 
-    r300_emit_query_end(r300);
-
     if (r300->dirty_hw) {
+        r300_emit_query_end(r300);
+
         FLUSH_CS;
         r300->dirty_hw = 0;
 
         /* New kitchen sink, baby. */
         foreach(atom, &r300->atom_list) {
-            if (atom->state) {
+            if (atom->state || atom->allow_null_state) {
                 atom->dirty = TRUE;
             }
         }
@@ -72,6 +75,39 @@ static void r300_flush(struct pipe_context* pipe,
     foreach(query, &r300->query_list) {
         query->flushed = TRUE;
     }
+
+    /* XXX
+     *
+     * This is a preliminary implementation of glFinish. Note that st/mesa
+     * uses a non-null fence when glFinish is called and then waits for
+     * the fence. Instead of returning the actual fence, we do the sync
+     * directly.
+     *
+     * The ideal implementation should use something like EmitIrqLocked and
+     * WaitIrq, or better, real fences.
+     *
+     * This feature degrades performance to the level of r300c for games that
+     * use glFinish a lot, even openarena does. Ideally we wouldn't need
+     * glFinish at all if we had proper throttling in swapbuffers so that
+     * the CPU wouldn't outrun the GPU by several frames, so this is basically
+     * a temporary fix for the input lag. Once swap&sync works with DRI2,
+     * I'll be happy to remove this code.
+     *
+     * - M. */
+    if (fence && r300->fb_state.state) {
+        fb = r300->fb_state.state;
+
+        for (i = 0; i < fb->nr_cbufs; i++) {
+            if (fb->cbufs[i]->texture) {
+                r300->rws->buffer_wait(r300->rws,
+                    r300_texture(fb->cbufs[i]->texture)->buffer);
+            }
+            if (fb->zsbuf) {
+                r300->rws->buffer_wait(r300->rws,
+                    r300_texture(fb->zsbuf->texture)->buffer);
+            }
+        }
+    }
 }
 
 void r300_init_flush_functions(struct r300_context* r300)
index 5c27796e894d3b93bac0c1c9621ee7983d6b7c6b..6acbac2219664411554c22b9b76ceb815d09f86a 100644 (file)
@@ -43,8 +43,6 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
     q->type = query_type;
     assert(q->type == PIPE_QUERY_OCCLUSION_COUNTER);
 
-    q->active = FALSE;
-
     if (r300screen->caps.family == CHIP_FAMILY_RV530)
         query_size = r300screen->caps.num_z_pipes * sizeof(uint32_t);
     else
@@ -59,6 +57,7 @@ static struct pipe_query *r300_create_query(struct pipe_context *pipe,
     /* XXX */
     if (q->offset >= 4096) {
         q->offset = 0;
+        fprintf(stderr, "r300: Rewinding OQBO...\n");
     }
 
     return (struct pipe_query*)q;
@@ -80,7 +79,12 @@ static void r300_begin_query(struct pipe_context* pipe,
     struct r300_context* r300 = r300_context(pipe);
     struct r300_query* q = (struct r300_query*)query;
 
-    assert(r300->query_current == NULL);
+    if (r300->query_current != NULL) {
+        fprintf(stderr, "r300: begin_query: "
+                "Some other query has already been started.\n");
+        assert(0);
+        return;
+    }
 
     pipe_buffer_write(pipe,
                      r300->oqbo,
@@ -97,10 +101,14 @@ static void r300_end_query(struct pipe_context* pipe,
                           struct pipe_query* query)
 {
     struct r300_context* r300 = r300_context(pipe);
-    struct r300_query* q = (struct r300_query*)query;
+
+    if ((struct r300_query*)query != r300->query_current) {
+        fprintf(stderr, "r300: end_query: Got invalid query.\n");
+        assert(0);
+        return;
+    }
 
     r300_emit_query_end(r300);
-    q->begin_emitted = false;
     r300->query_current = NULL;
 }
 
index 8795410efde5604e65b82b764ec7c608e3f3d2e0..e1f61982be223c8571e286b0976690c92ff6155a 100644 (file)
@@ -735,6 +735,8 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe,
         return;
     }
 
+    r300_update_derived_state(r300);
+
     for (i = 0; i < r300->vertex_buffer_count; i++) {
         void* buf = pipe_buffer_map(pipe,
                                     r300->vertex_buffer[i].buffer,
@@ -747,6 +749,10 @@ void r300_swtcl_draw_arrays(struct pipe_context* pipe,
 
     draw_arrays(r300->draw, mode, start, count);
 
+    /* XXX Not sure whether this is the best fix.
+     * It prevents CS from being rejected and weird assertion failures. */
+    draw_flush(r300->draw);
+
     for (i = 0; i < r300->vertex_buffer_count; i++) {
         pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
                          vb_transfer[i]);
@@ -779,6 +785,8 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
         return;
     }
 
+    r300_update_derived_state(r300);
+
     for (i = 0; i < r300->vertex_buffer_count; i++) {
         void* buf = pipe_buffer_map(pipe,
                                     r300->vertex_buffer[i].buffer,
@@ -794,6 +802,10 @@ void r300_swtcl_draw_range_elements(struct pipe_context* pipe,
 
     draw_arrays(r300->draw, mode, start, count);
 
+    /* XXX Not sure whether this is the best fix.
+     * It prevents CS from being rejected and weird assertion failures. */
+    draw_flush(r300->draw);
+
     for (i = 0; i < r300->vertex_buffer_count; i++) {
         pipe_buffer_unmap(pipe, r300->vertex_buffer[i].buffer,
                          vb_transfer[i]);
@@ -827,7 +839,7 @@ struct r300_render {
     size_t vbo_max_used;
     void * vbo_ptr;
 
-   struct pipe_transfer *vbo_transfer;
+    struct pipe_transfer *vbo_transfer;
 };
 
 static INLINE struct r300_render*
@@ -842,8 +854,6 @@ r300_render_get_vertex_info(struct vbuf_render* render)
     struct r300_render* r300render = r300_render(render);
     struct r300_context* r300 = r300render->r300;
 
-    r300_update_derived_state(r300);
-
     return &r300->vertex_info;
 }
 
@@ -891,10 +901,6 @@ static void r300_render_unmap_vertices(struct vbuf_render* render,
 {
     struct r300_render* r300render = r300_render(render);
     struct pipe_context* context = &r300render->r300->context;
-    CS_LOCALS(r300render->r300);
-    BEGIN_CS(2);
-    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max);
-    END_CS;
 
     r300render->vbo_max_used = MAX2(r300render->vbo_max_used,
                                     r300render->vertex_size * (max + 1));
@@ -928,10 +934,13 @@ static void r500_render_draw_arrays(struct vbuf_render* render,
     struct r300_context* r300 = r300render->r300;
     uint8_t* ptr;
     unsigned i;
+    unsigned dwords = 6;
 
     CS_LOCALS(r300);
 
-    r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, 2, 0, 0);
+    (void) i; (void) ptr;
+
+    r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
 
     DBG(r300, DBG_DRAW, "r300: Doing vbuf render, count %d\n", count);
 
@@ -952,7 +961,10 @@ static void r500_render_draw_arrays(struct vbuf_render* render,
         r300render->vbo_transfer);
     */
 
-    BEGIN_CS(2);
+    BEGIN_CS(dwords);
+    OUT_CS_REG(R300_GA_COLOR_CONTROL,
+            r300_provoking_vertex_fixes(r300, r300render->prim));
+    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, count - 1);
     OUT_CS_PKT3(R300_PACKET3_3D_DRAW_VBUF_2, 0);
     OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_VERTEX_LIST | (count << 16) |
            r300render->hwprim);
@@ -966,13 +978,18 @@ static void r500_render_draw_elements(struct vbuf_render* render,
     struct r300_render* r300render = r300_render(render);
     struct r300_context* r300 = r300render->r300;
     int i;
-    unsigned dwords = 2 + (count+1)/2;
+    unsigned dwords = 6 + (count+1)/2;
+    unsigned max_index = (r300render->vbo_size - r300render->vbo_offset) /
+                         (r300render->r300->vertex_info.size * 4) - 1;
 
     CS_LOCALS(r300);
 
     r300_prepare_for_rendering(r300, PREP_FIRST_DRAW, NULL, dwords, 0, 0);
 
     BEGIN_CS(dwords);
+    OUT_CS_REG(R300_GA_COLOR_CONTROL,
+            r300_provoking_vertex_fixes(r300, r300render->prim));
+    OUT_CS_REG(R300_VAP_VF_MAX_VTX_INDX, max_index);
     OUT_CS_PKT3(R300_PACKET3_3D_DRAW_INDX_2, (count+1)/2);
     OUT_CS(R300_VAP_VF_CNTL__PRIM_WALK_INDICES | (count << 16) |
            r300render->hwprim);
index 8399f5df8e43f379d3bcc9a7e1da8db1ccc7a76b..640b3d346887fbd6f70d5d69cb87e46b025ca74c 100644 (file)
@@ -115,6 +115,7 @@ static int r300_get_param(struct pipe_screen* pscreen, enum pipe_cap param)
             return 1;
 
         /* Unsupported features (boolean caps). */
+        case PIPE_CAP_TIMER_QUERY:
         case PIPE_CAP_DUAL_SOURCE_BLEND:
         case PIPE_CAP_TGSI_CONT_SUPPORTED:
         case PIPE_CAP_INDEP_BLEND_ENABLE:
index d58aa138a704c3d96e90ce45eba28ee11252ddd8..29492024fe3ab92c46411eec07031cb73eb1bea1 100644 (file)
@@ -61,19 +61,23 @@ static INLINE struct r300_screen* r300_screen(struct pipe_screen* screen) {
  * those changes.
  */
 /*@{*/
-#define DBG_HELP    0x0000001
-#define DBG_FP      0x0000002
-#define DBG_VP      0x0000004
-#define DBG_CS      0x0000008
-#define DBG_DRAW    0x0000010
-#define DBG_TEX     0x0000020
-#define DBG_FALL    0x0000040
-#define DBG_ANISOHQ 0x0000080
-#define DBG_NO_TILING 0x0000100
-#define DBG_NO_IMMD 0x0000200
-#define DBG_STATS   0x0000400
-#define DBG_RS      0x0000800
-#define DBG_TEXALLOC 0x0001000
+#define DBG_HELP        (1 << 0)
+/* Logging. */
+#define DBG_FP          (1 << 1)
+#define DBG_VP          (1 << 2)
+#define DBG_CS          (1 << 3)
+#define DBG_DRAW        (1 << 4)
+#define DBG_TEX         (1 << 5)
+#define DBG_TEXALLOC    (1 << 6)
+#define DBG_RS          (1 << 7)
+#define DBG_FALL        (1 << 8)
+#define DBG_FB          (1 << 9)
+/* Features. */
+#define DBG_ANISOHQ     (1 << 16)
+#define DBG_NO_TILING   (1 << 17)
+#define DBG_NO_IMMD     (1 << 18)
+/* Statistics. */
+#define DBG_STATS       (1 << 24)
 /*@}*/
 
 static INLINE boolean SCREEN_DBG_ON(struct r300_screen * screen, unsigned flags)
index 006a34119b7f61e4092c311badf757287b8fb527..11c10e2f2a85e360835334c7f46827e3910a3785 100644 (file)
@@ -566,13 +566,35 @@ static void r300_fb_set_tiling_flags(struct r300_context *r300,
     }
 }
 
+static void r300_print_fb_surf_info(struct pipe_surface *surf, unsigned index,
+                                    const char *binding)
+{
+    struct pipe_resource *tex = surf->texture;
+    struct r300_texture *rtex = r300_texture(tex);
+
+    fprintf(stderr,
+            "r300:   %s[%i] Dim: %ix%i, Offset: %i, ZSlice: %i, "
+            "Face: %i, Level: %i, Format: %s\n"
+
+            "r300:     TEX: Macro: %s, Micro: %s, Pitch: %i, "
+            "Dim: %ix%ix%i, LastLevel: %i, Format: %s\n",
+
+            binding, index, surf->width, surf->height, surf->offset,
+            surf->zslice, surf->face, surf->level,
+            util_format_short_name(surf->format),
+
+            rtex->macrotile ? "YES" : " NO", rtex->microtile ? "YES" : " NO",
+            rtex->hwpitch[0], tex->width0, tex->height0, tex->depth0,
+            tex->last_level, util_format_short_name(tex->format));
+}
+
 static void
     r300_set_framebuffer_state(struct pipe_context* pipe,
                                const struct pipe_framebuffer_state* state)
 {
     struct r300_context* r300 = r300_context(pipe);
     struct pipe_framebuffer_state *old_state = r300->fb_state.state;
-    unsigned max_width, max_height;
+    unsigned max_width, max_height, i;
     uint32_t zbuffer_bpp = 0;
 
     if (state->nr_cbufs > 4) {
@@ -634,6 +656,16 @@ static void
             r300->rs_state.dirty = TRUE;
         }
     }
+
+    if (DBG_ON(r300, DBG_FB)) {
+        fprintf(stderr, "r300: set_framebuffer_state:\n");
+        for (i = 0; i < state->nr_cbufs; i++) {
+            r300_print_fb_surf_info(state->cbufs[i], i, "CB");
+        }
+        if (state->zsbuf) {
+            r300_print_fb_surf_info(state->zsbuf, 0, "ZB");
+        }
+    }
 }
 
 /* Create fragment shader state. */
@@ -724,8 +756,12 @@ static void* r300_create_rs_state(struct pipe_context* pipe,
     int i;
     float psiz;
 
-    /* Copy rasterizer state for Draw. */
+    /* Copy rasterizer state. */
     rs->rs = *state;
+    rs->rs_draw = *state;
+
+    /* Override some states for Draw. */
+    rs->rs_draw.sprite_coord_enable = 0; /* We can do this in HW. */
 
 #ifdef PIPE_ARCH_LITTLE_ENDIAN
     rs->vap_control_status = R300_VC_NO_SWAP;
@@ -856,9 +892,9 @@ static void r300_bind_rs_state(struct pipe_context* pipe, void* state)
     int last_sprite_coord_enable = r300->sprite_coord_enable;
     boolean last_two_sided_color = r300->two_sided_color;
 
-    if (r300->draw) {
+    if (r300->draw && rs) {
         draw_flush(r300->draw);
-        draw_set_rasterizer_state(r300->draw, &rs->rs, state);
+        draw_set_rasterizer_state(r300->draw, &rs->rs_draw, state);
     }
 
     if (rs) {
@@ -1200,7 +1236,7 @@ static void r300_set_vertex_buffers(struct pipe_context* pipe,
     }
 }
 
-/* Update the PSC tables. */
+/* Initialize the PSC tables. */
 static void r300_vertex_psc(struct r300_vertex_element_state *velems)
 {
     struct r300_vertex_stream_state *vstream = &velems->vertex_stream;
@@ -1339,7 +1375,6 @@ static void* r300_create_vertex_elements_state(struct pipe_context* pipe,
                     abort();
                 }
             }
-
         }
     }
     return velems;
@@ -1360,6 +1395,7 @@ static void r300_bind_vertex_elements_state(struct pipe_context *pipe,
     if (r300->draw) {
         draw_flush(r300->draw);
         draw_set_vertex_elements(r300->draw, velems->count, velems->velem);
+        return;
     }
 
     UPDATE_STATE(&velems->vertex_stream, r300->vertex_stream_state);
@@ -1382,8 +1418,10 @@ static void* r300_create_vs_state(struct pipe_context* pipe,
     vs->state = *shader;
     vs->state.tokens = tgsi_dup_tokens(shader->tokens);
 
+    r300_init_vs_outputs(vs);
+
     if (r300->screen->caps.has_tcl) {
-        r300_translate_vertex_shader(r300, vs, vs->state.tokens);
+        r300_translate_vertex_shader(r300, vs);
     } else {
         vs->draw_vs = draw_create_vertex_shader(r300->draw, shader);
     }
@@ -1453,7 +1491,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
     struct r300_constant_buffer *cbuf;
     struct pipe_transfer *tr;
     void *mapped;
-    int max_size = 0;
+    int max_size = 0, max_size_bytes = 0, clamped_size = 0;
 
     switch (shader) {
         case PIPE_SHADER_VERTEX:
@@ -1472,6 +1510,7 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
             assert(0);
             return;
     }
+    max_size_bytes = max_size * 4 * sizeof(float);
 
     if (buf == NULL || buf->width0 == 0 ||
         (mapped = pipe_buffer_map(pipe, buf, PIPE_TRANSFER_READ, &tr)) == NULL)
@@ -1480,19 +1519,21 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
         return;
     }
 
-    assert((buf->width0 % 4 * sizeof(float)) == 0);
+    if (shader == PIPE_SHADER_FRAGMENT ||
+        (shader == PIPE_SHADER_VERTEX && r300->screen->caps.has_tcl)) {
+        assert((buf->width0 % (4 * sizeof(float))) == 0);
 
-    /* Check the size of the constant buffer. */
-    /* XXX Subtract immediates and RC_STATE_* variables. */
-    if (buf->width0 > (sizeof(float) * 4 * max_size)) {
-        fprintf(stderr, "r300: Max size of the constant buffer is "
-                      "%i*4 floats.\n", max_size);
-        abort();
-    }
+        /* Check the size of the constant buffer. */
+        /* XXX Subtract immediates and RC_STATE_* variables. */
+        if (buf->width0 > max_size_bytes) {
+            fprintf(stderr, "r300: Max size of the constant buffer is "
+                          "%i*4 floats.\n", max_size);
+        }
+        clamped_size = MIN2(buf->width0, max_size_bytes);
 
-    memcpy(cbuf->constants, mapped, buf->width0);
-    cbuf->count = buf->width0 / (4 * sizeof(float));
-    pipe_buffer_unmap(pipe, buf, tr);
+        memcpy(cbuf->constants, mapped, clamped_size);
+        cbuf->count = clamped_size / (4 * sizeof(float));
+    }
 
     if (shader == PIPE_SHADER_VERTEX) {
         if (r300->screen->caps.has_tcl) {
@@ -1502,12 +1543,13 @@ static void r300_set_constant_buffer(struct pipe_context *pipe,
             r300->pvs_flush.dirty = TRUE;
         } else if (r300->draw) {
             draw_set_mapped_constant_buffer(r300->draw, PIPE_SHADER_VERTEX,
-                0, cbuf->constants,
-                buf->width0);
+                0, mapped, buf->width0);
         }
     } else if (shader == PIPE_SHADER_FRAGMENT) {
         r300->fs_constants.dirty = TRUE;
     }
+
+    pipe_buffer_unmap(pipe, buf, tr);
 }
 
 void r300_init_state_functions(struct r300_context* r300)
index c7388998270a28e2e23545412330608b1d7d9a64..7583862a1a4baed83a9033fdef0a7744b3231ad8 100644 (file)
@@ -116,13 +116,12 @@ static void r300_draw_emit_all_attribs(struct r300_context* r300)
 static void r300_swtcl_vertex_psc(struct r300_context *r300)
 {
     struct r300_vertex_stream_state *vstream = r300->vertex_stream_state.state;
-        struct vertex_info* vinfo = &r300->vertex_info;
+    struct vertex_info *vinfo = &r300->vertex_info;
     uint16_t type, swizzle;
     enum pipe_format format;
     unsigned i, attrib_count;
     int* vs_output_tab = r300->stream_loc_notcl;
 
-    /* XXX hax */
     memset(vstream, 0, sizeof(struct r300_vertex_stream_state));
 
     /* For each Draw attribute, route it to the fragment shader according
@@ -615,13 +614,13 @@ void r300_update_derived_state(struct r300_context* r300)
 
     if (r300->rs_block_state.dirty) {
         r300_update_rs_block(r300);
-    }
 
-    if (r300->draw) {
-        memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
-        r300_draw_emit_all_attribs(r300);
-        draw_compute_vertex_size(&r300->vertex_info);
-        r300_swtcl_vertex_psc(r300);
+        if (r300->draw) {
+            memset(&r300->vertex_info, 0, sizeof(struct vertex_info));
+            r300_draw_emit_all_attribs(r300);
+            draw_compute_vertex_size(&r300->vertex_info);
+            r300_swtcl_vertex_psc(r300);
+        }
     }
 
     r300_update_hyperz_state(r300);
index f3186431e1d170e66fa916b7e401fe9115e422fc..59f89b3482ab7e07c3c5edb8022e81c88ff4671a 100644 (file)
@@ -181,21 +181,23 @@ static void r300_dummy_vertex_shader(
     state.tokens = ureg_finalize(ureg);
 
     shader->dummy = TRUE;
-    r300_translate_vertex_shader(r300, shader, state.tokens);
+    r300_translate_vertex_shader(r300, shader);
 
     ureg_destroy(ureg);
 }
 
-void r300_translate_vertex_shader(struct r300_context* r300,
-                                  struct r300_vertex_shader* vs,
-                                  const struct tgsi_token *tokens)
+void r300_init_vs_outputs(struct r300_vertex_shader *vs)
+{
+    tgsi_scan_shader(vs->state.tokens, &vs->info);
+    r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
+}
+
+void r300_translate_vertex_shader(struct r300_context *r300,
+                                  struct r300_vertex_shader *vs)
 {
     struct r300_vertex_program_compiler compiler;
     struct tgsi_to_rc ttr;
 
-    tgsi_scan_shader(tokens, &vs->info);
-    r300_shader_read_vs_outputs(&vs->info, &vs->outputs);
-
     /* Setup the compiler */
     rc_init(&compiler.Base);
 
@@ -205,7 +207,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
 
     if (compiler.Base.Debug) {
         debug_printf("r300: Initial vertex program\n");
-        tgsi_dump(tokens, 0);
+        tgsi_dump(vs->state.tokens, 0);
     }
 
     /* Translate TGSI to our internal representation */
@@ -213,7 +215,7 @@ void r300_translate_vertex_shader(struct r300_context* r300,
     ttr.info = &vs->info;
     ttr.use_half_swizzles = FALSE;
 
-    r300_tgsi_to_rc(&ttr, tokens);
+    r300_tgsi_to_rc(&ttr, vs->state.tokens);
 
     compiler.RequiredOutputs = ~(~0 << (vs->info.num_outputs + 1));
     compiler.SetHwInputOutput = &set_vertex_inputs_outputs;
index 57b3fbca0bb7216d64e1ab4a0ce0228c94279e41..31890d78caf076b501e4f6564bbc07624ffb3528 100644 (file)
@@ -56,8 +56,8 @@ struct r300_vertex_shader {
     void *draw_vs;
 };
 
-void r300_translate_vertex_shader(struct r300_context* r300,
-                                  struct r300_vertex_shader* vs,
-                                  const struct tgsi_token *tokens);
+void r300_init_vs_outputs(struct r300_vertex_shader *vs);
 
+void r300_translate_vertex_shader(struct r300_context *r300,
+                                  struct r300_vertex_shader *vs);
 #endif /* R300_VS_H */
index 1642981eaa8328d11b077aa4697a1ed5c909d2f8..3d0413f90af4f20ee4a5add95c923041ddf6b88f 100644 (file)
@@ -87,13 +87,8 @@ struct r300_winsys_screen {
                             struct r300_winsys_buffer **pdst,
                             struct r300_winsys_buffer *src);
 
-    boolean (*buffer_references)(struct r300_winsys_buffer *a,
-                                struct r300_winsys_buffer *b);
-
-    void (*buffer_flush_range)(struct r300_winsys_screen *rws,
-                              struct r300_winsys_buffer *buf,
-                              unsigned offset,
-                              unsigned length);
+    void (*buffer_wait)(struct r300_winsys_screen *rws,
+                        struct r300_winsys_buffer *buf);
 
     /* Add a pipe_resource to the list of buffer objects to validate. */
     boolean (*add_buffer)(struct r300_winsys_screen *winsys,
index 7d7b9247c35b395149c5db54cc747fdbb02d9138..2b60af2302a6fa3d21bc42aa6e1d1bea13c08f06 100644 (file)
@@ -37,7 +37,7 @@
 #include "rbug_context.h"
 #include "rbug_objects.h"
 
-DEBUG_GET_ONCE_BOOL_OPTION(rbug, "GALLIUM_RBUG", FALSE);
+DEBUG_GET_ONCE_BOOL_OPTION(rbug, "GALLIUM_RBUG", FALSE)
 
 static void
 rbug_screen_destroy(struct pipe_screen *_screen)
index 4ef5d9f7b1db3e3172bd272d72b5ce4e5647722d..b959af63aff59e6ebe8a24d4b18bb39a85664bd2 100644 (file)
@@ -30,6 +30,7 @@
  */
 
 #include "draw/draw_context.h"
+#include "os/os_time.h"
 #include "pipe/p_defines.h"
 #include "util/u_memory.h"
 #include "sp_context.h"
@@ -37,6 +38,7 @@
 #include "sp_state.h"
 
 struct softpipe_query {
+   unsigned type;
    uint64_t start;
    uint64_t end;
 };
@@ -51,8 +53,13 @@ static struct pipe_query *
 softpipe_create_query(struct pipe_context *pipe, 
                      unsigned type)
 {
-   assert(type == PIPE_QUERY_OCCLUSION_COUNTER);
-   return (struct pipe_query *)CALLOC_STRUCT( softpipe_query );
+   struct softpipe_query* sq;
+
+   assert(type == PIPE_QUERY_OCCLUSION_COUNTER || type == PIPE_QUERY_TIME_ELAPSED);
+   sq = CALLOC_STRUCT( softpipe_query );
+   sq->type = type;
+
+   return (struct pipe_query *)sq;
 }
 
 
@@ -69,7 +76,17 @@ softpipe_begin_query(struct pipe_context *pipe, struct pipe_query *q)
    struct softpipe_context *softpipe = softpipe_context( pipe );
    struct softpipe_query *sq = softpipe_query(q);
    
-   sq->start = softpipe->occlusion_count;
+   switch (sq->type) {
+   case PIPE_QUERY_OCCLUSION_COUNTER:
+      sq->start = softpipe->occlusion_count;
+      break;
+   case PIPE_QUERY_TIME_ELAPSED:
+      sq->start = 1000*os_time_get();
+      break;
+   default:
+      assert(0);
+      break;
+   }
    softpipe->active_query_count++;
    softpipe->dirty |= SP_NEW_QUERY;
 }
@@ -82,7 +99,17 @@ softpipe_end_query(struct pipe_context *pipe, struct pipe_query *q)
    struct softpipe_query *sq = softpipe_query(q);
 
    softpipe->active_query_count--;
-   sq->end = softpipe->occlusion_count;
+   switch (sq->type) {
+   case PIPE_QUERY_OCCLUSION_COUNTER:
+      sq->end = softpipe->occlusion_count;
+      break;
+   case PIPE_QUERY_TIME_ELAPSED:
+      sq->end = 1000*os_time_get();
+      break;
+   default:
+      assert(0);
+      break;
+   }
    softpipe->dirty |= SP_NEW_QUERY;
 }
 
index f874c3e60c029a410c3f02fee617150e1b91f319..8c33efa1987104bad3c69d9f7723f68bca0b2000 100644 (file)
@@ -82,6 +82,8 @@ softpipe_get_param(struct pipe_screen *screen, enum pipe_cap param)
       return PIPE_MAX_COLOR_BUFS;
    case PIPE_CAP_OCCLUSION_QUERY:
       return 1;
+   case PIPE_CAP_TIMER_QUERY:
+      return 1;
    case PIPE_CAP_TEXTURE_MIRROR_CLAMP:
       return 1;
    case PIPE_CAP_TEXTURE_MIRROR_REPEAT:
index 7aa85559b236d0d3a8dfa6f79782b8e0a5752c53..4e6123fbd07834303e2cc9ed07265f0c45c2b37f 100644 (file)
@@ -343,11 +343,15 @@ softpipe_get_transfer(struct pipe_context *pipe,
    if (spt) {
       struct pipe_transfer *pt = &spt->base;
       enum pipe_format format = resource->format;
+      const unsigned hgt = u_minify(spr->base.height0, sr.level);
+      const unsigned nblocksy = util_format_get_nblocksy(format, hgt);
+
       pipe_resource_reference(&pt->resource, resource);
       pt->sr = sr;
       pt->usage = usage;
       pt->box = *box;
       pt->stride = spr->stride[sr.level];
+      pt->slice_stride = pt->stride * nblocksy;
 
       spt->offset = sp_get_tex_image_offset(spr, sr.level, sr.face, box->z);
  
index 2c3c3f522020901b492b55e2442cb1f2c9cbe76f..bef22f41ae5d2bdf5d44014c3c93bbec28bf3938 100644 (file)
@@ -134,6 +134,8 @@ svga_get_paramf(struct pipe_screen *screen, enum pipe_cap param)
       return MIN2(result.u, PIPE_MAX_COLOR_BUFS);
    case PIPE_CAP_OCCLUSION_QUERY:
       return 1;
+   case PIPE_CAP_TIMER_QUERY:
+      return 0;
    case PIPE_CAP_TEXTURE_SHADOW_MAP:
       return 1;
 
index 8724690f7e1da2489255801024d8da624e46db27..65c675f99c94cd6269d86d1a39a49dea2375184c 100644 (file)
@@ -30,7 +30,6 @@
 
 struct svga_context;
 struct pipe_context;
-struct pipe_buffer;
 struct vbuf_render;
 
 
index f21f72b0c7958b4710f00df24f689c0a94f6b3bd..74c5e83e9e1686da1a681886ae5525a0218755ce 100644 (file)
@@ -37,7 +37,6 @@
 #include "pipe/p_compiler.h"
 #include "pipe/p_format.h"
 
-struct pipe_buffer;
 struct pipe_resource;
 struct pipe_surface;
 struct pipe_transfer;
index bed480f75edba77ccb2bac8db3424b262b9f2074..8201c29ac7622a312251b708d02d823101fbbc2a 100644 (file)
@@ -379,7 +379,8 @@ enum pipe_transfer_usage {
 #define PIPE_QUERY_OCCLUSION_COUNTER     0
 #define PIPE_QUERY_PRIMITIVES_GENERATED  1
 #define PIPE_QUERY_PRIMITIVES_EMITTED    2
-#define PIPE_QUERY_TYPES                 3
+#define PIPE_QUERY_TIME_ELAPSED          3
+#define PIPE_QUERY_TYPES                 4
 
 
 /**
@@ -423,6 +424,7 @@ enum pipe_cap {
    PIPE_CAP_POINT_SPRITE,
    PIPE_CAP_MAX_RENDER_TARGETS,
    PIPE_CAP_OCCLUSION_QUERY,
+   PIPE_CAP_TIMER_QUERY,
    PIPE_CAP_TEXTURE_SHADOW_MAP,
    PIPE_CAP_MAX_TEXTURE_2D_LEVELS,
    PIPE_CAP_MAX_TEXTURE_3D_LEVELS,
index 7195dc03963b3a7e781b061ed871c6b00a4acd4c..0d9de48c9094a9fbd2ad0241cd6d3dd031905ea0 100644 (file)
@@ -54,7 +54,6 @@ struct winsys_handle;
 /** Opaque type */
 struct pipe_fence_handle;
 struct pipe_winsys;
-struct pipe_texture;
 struct pipe_resource;
 struct pipe_surface;
 struct pipe_transfer;
index a48c5de5a0598e8f86e80f89d72f358ab195b19f..0d702d909287fc04be31a1e91d50560089543e96 100644 (file)
@@ -9,7 +9,6 @@
 
 struct pipe_screen;
 struct pipe_winsys;
-struct pipe_buffer;
 struct pipe_context;
 struct pipe_resource;
 
index 3d8fdd86fc7552ab3fba1aa27bbf6d8c35f22d7f..8fd0995444dde5f96b7d07d0ad90b777e988ca6b 100644 (file)
@@ -6,7 +6,6 @@
 
 struct pipe_screen;
 struct pipe_winsys;
-struct pipe_buffer;
 struct pipe_context;
 struct pipe_resource;
 
index 385e4d7718eadedcf0237b9081ce2849fdbc8c62..e5b298e03d9ddb47569b8ee44c118ebc2cc2cd26 100644 (file)
 #include "pipe/p_format.h"
 
 struct pipe_screen;
-
-PUBLIC struct pipe_screen *graw_init( void );
+struct pipe_context;
 
 /* Returns a handle to be used with flush_frontbuffer()/present().
  *
  * Query format support with screen::is_format_supported and usage
  * XXX.
  */
-PUBLIC void *graw_create_window( int x,
-                                 int y,
-                                 unsigned width,
-                                 unsigned height,
-                                 enum pipe_format format );
+PUBLIC struct pipe_screen *graw_create_window_and_screen( int x,
+                                                          int y,
+                                                          unsigned width,
+                                                          unsigned height,
+                                                          enum pipe_format format,
+                                                          void **handle);
+
+PUBLIC void graw_set_display_func( void (*func)( void ) );
+PUBLIC void graw_main_loop( void );
+
+PUBLIC void *graw_parse_vertex_shader( struct pipe_context *pipe,
+                                       const char *text );
 
-PUBLIC void graw_destroy_window( void *handle );
+PUBLIC void *graw_parse_fragment_shader( struct pipe_context *pipe,
+                                         const char *text );
 
 #endif
index bd4a85caa0431825f4f6164361125572a6722999..26fcae78eceeecedf112305019b55df11a412075 100644 (file)
@@ -34,7 +34,6 @@
 #include <string.h>
 #include "GL/glx.h"
 #include "glapi/glapi.h"
-#include "pipe/p_compiler.h"
 
 
 struct name_address_pair {
index 669bd9edcf01de0b76828aca82e1e1bbbaead75a..f9022a9f934bdb33cc93957ee06bd5aca5847bb2 100644 (file)
@@ -90,11 +90,10 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
     xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(crtc->scrn);
     modesettingPtr ms = modesettingPTR(crtc->scrn);
     xf86OutputPtr output = NULL;
-    drmModeConnectorPtr drm_connector;
     struct crtc_private *crtcp = crtc->driver_private;
     drmModeCrtcPtr drm_crtc = crtcp->drm_crtc;
     drmModeModeInfo drm_mode;
-    int i, ret;
+    int i, ret, connector_id;
 
     for (i = 0; i < config->num_output; output = NULL, i++) {
        output = config->output[i];
@@ -106,7 +105,7 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
     if (!output)
        return FALSE;
 
-    drm_connector = output->driver_private;
+    connector_id = xorg_output_get_id(output);
 
     drm_mode.clock = mode->Clock;
     drm_mode.hdisplay = mode->HDisplay;
@@ -127,7 +126,7 @@ crtc_set_mode_major(xf86CrtcPtr crtc, DisplayModePtr mode,
     drm_mode.name[DRM_DISPLAY_MODE_LEN - 1] = '\0';
 
     ret = drmModeSetCrtc(ms->fd, drm_crtc->crtc_id, ms->fb_id, x, y,
-                        &drm_connector->connector_id, 1, &drm_mode);
+                        &connector_id, 1, &drm_mode);
 
     if (ret)
        return FALSE;
index b90f9c908d2a28ed03072d0a4bd1b9d40bc41ed9..921b6900fcd7cbdfb9c12a6677b2a0e7dd087725 100644 (file)
@@ -403,7 +403,7 @@ xorg_dri2_init(ScreenPtr pScreen)
     }
 #endif
 
-    dri2info.version = DRI2INFOREC_VERSION;
+    dri2info.version = min(DRI2INFOREC_VERSION, 3);
     dri2info.fd = ms->fd;
 
     dri2info.driverName = pScrn->driverName;
index 3687ee0db4e399405a239d25f20f493ae748a650..44520b81b663a52d0d2f8583be254fc60bf1bfd7 100644 (file)
@@ -141,8 +141,6 @@ xorg_tracker_have_modesetting(ScrnInfoPtr pScrn, struct pci_device *device)
 
 static Bool drv_init_front_buffer_functions(ScrnInfoPtr pScrn);
 static Bool drv_close_screen(int scrnIndex, ScreenPtr pScreen);
-static Bool drv_save_hw_state(ScrnInfoPtr pScrn);
-static Bool drv_restore_hw_state(ScrnInfoPtr pScrn);
 
 
 /*
@@ -336,17 +334,9 @@ static Bool
 drv_close_resource_management(ScrnInfoPtr pScrn)
 {
     modesettingPtr ms = modesettingPTR(pScrn);
-    int i;
 
     if (ms->screen) {
        assert(ms->ctx == NULL);
-
-       for (i = 0; i < XORG_NR_FENCES; i++) {
-           if (ms->fence[i]) {
-               ms->screen->fence_finish(ms->screen, ms->fence[i], 0);
-               ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL);
-           }
-       }
        ms->screen->destroy(ms->screen);
     }
     ms->screen = NULL;
@@ -359,6 +349,22 @@ drv_close_resource_management(ScrnInfoPtr pScrn)
     return TRUE;
 }
 
+static void
+drv_cleanup_fences(ScrnInfoPtr pScrn)
+{
+    modesettingPtr ms = modesettingPTR(pScrn);
+    int i;
+
+    assert(ms->screen);
+
+    for (i = 0; i < XORG_NR_FENCES; i++) {
+       if (ms->fence[i]) {
+           ms->screen->fence_finish(ms->screen, ms->fence[i], 0);
+           ms->screen->fence_reference(ms->screen, &ms->fence[i], NULL);
+       }
+    }
+}
+
 static Bool
 drv_pre_init(ScrnInfoPtr pScrn, int flags)
 {
@@ -388,7 +394,6 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
        return FALSE;
 
     ms = modesettingPTR(pScrn);
-    ms->SaveGeneration = -1;
     ms->pEnt = pEnt;
     ms->cust = cust;
 
@@ -471,19 +476,14 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
        ms->SWCursor = TRUE;
     }
 
-    drv_save_hw_state(pScrn);
-
     xorg_crtc_init(pScrn);
     xorg_output_init(pScrn);
 
     if (!xf86InitialConfiguration(pScrn, TRUE)) {
        xf86DrvMsg(pScrn->scrnIndex, X_ERROR, "No valid modes.\n");
-       drv_restore_hw_state(pScrn);
        return FALSE;
     }
 
-    drv_restore_hw_state(pScrn);
-
     /*
      * If the driver can do gamma correction, it should call xf86SetGamma() here.
      */
@@ -521,22 +521,6 @@ drv_pre_init(ScrnInfoPtr pScrn, int flags)
     return TRUE;
 }
 
-static Bool
-drv_save_hw_state(ScrnInfoPtr pScrn)
-{
-    /*xf86CrtcConfigPtr xf86_config = XF86_CRTC_CONFIG_PTR(pScrn);*/
-
-    return TRUE;
-}
-
-static Bool
-drv_restore_hw_state(ScrnInfoPtr pScrn)
-{
-    /*xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(pScrn);*/
-
-    return TRUE;
-}
-
 static void drv_block_handler(int i, pointer blockData, pointer pTimeout,
                               pointer pReadmask)
 {
@@ -848,7 +832,9 @@ drv_leave_vt(int scrnIndex, int flags)
     drmModeRmFB(ms->fd, ms->fb_id);
     ms->fb_id = -1;
 
-    drv_restore_hw_state(pScrn);
+    /* idle hardware */
+    if (!ms->kms)
+       drv_cleanup_fences(pScrn);
 
     if (drmDropMaster(ms->fd))
        xf86DrvMsg(pScrn->scrnIndex, X_WARNING,
@@ -878,15 +864,6 @@ drv_enter_vt(int scrnIndex, int flags)
        }
     }
 
-    /*
-     * Only save state once per server generation since that's what most
-     * drivers do.  Could change this to save state at each VT enter.
-     */
-    if (ms->SaveGeneration != serverGeneration) {
-       ms->SaveGeneration = serverGeneration;
-       drv_save_hw_state(pScrn);
-    }
-
     if (!ms->create_front_buffer(pScrn))
        return FALSE;
 
@@ -917,10 +894,6 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
     modesettingPtr ms = modesettingPTR(pScrn);
     CustomizerPtr cust = ms->cust;
 
-    if (pScrn->vtSema) {
-       drv_leave_vt(scrnIndex, 0);
-    }
-
     if (ms->cursor) {
        FreeCursor(ms->cursor, None);
        ms->cursor = NULL;
@@ -952,6 +925,11 @@ drv_close_screen(int scrnIndex, ScreenPtr pScreen)
        xorg_exa_close(pScrn);
     ms->exa = NULL;
 
+    /* calls drop master make sure we don't talk to 3D HW after that */
+    if (pScrn->vtSema) {
+       drv_leave_vt(scrnIndex, 0);
+    }
+
     drv_close_resource_management(pScrn);
 
     drv_close_drm(pScrn);
index 65be8c332a5da8b4f3180562d1efaf0f524cfc8c..31140f13bb4d2a389f32aca5098d28054c64d72d 100644 (file)
@@ -981,6 +981,8 @@ xorg_exa_close(ScrnInfoPtr pScrn)
 
    renderer_destroy(exa->renderer);
 
+   xorg_exa_finish(exa);
+
    if (exa->pipe)
       exa->pipe->destroy(exa->pipe);
    exa->pipe = NULL;
index 13c3fb97e3bd8b1581b5ce290cbd15e781f5e6f3..056098f76b41f815807cf10ffdc72efc75fdce51 100644 (file)
 
 #include "xorg_tracker.h"
 
+struct output_private
+{
+    drmModeConnectorPtr drm_connector;
+
+    int c;
+};
+
 static char *output_enum_list[] = {
     "Unknown",
     "VGA",
@@ -82,22 +89,38 @@ output_dpms(xf86OutputPtr output, int mode)
 static xf86OutputStatus
 output_detect(xf86OutputPtr output)
 {
-    drmModeConnectorPtr drm_connector = output->driver_private;
+    modesettingPtr ms = modesettingPTR(output->scrn);
+    struct output_private *priv = output->driver_private;
+    drmModeConnectorPtr drm_connector;
+    xf86OutputStatus status;
+
+    drm_connector = drmModeGetConnector(ms->fd, priv->drm_connector->connector_id);
+    if (drm_connector) {
+       drmModeFreeConnector(priv->drm_connector);
+       priv->drm_connector = drm_connector;
+    } else {
+       drm_connector = priv->drm_connector;
+    }
 
     switch (drm_connector->connection) {
     case DRM_MODE_CONNECTED:
-       return XF86OutputStatusConnected;
+       status = XF86OutputStatusConnected;
+       break;
     case DRM_MODE_DISCONNECTED:
-       return XF86OutputStatusDisconnected;
+       status = XF86OutputStatusDisconnected;
+       break;
     default:
-       return XF86OutputStatusUnknown;
+       status = XF86OutputStatusUnknown;
     }
+
+    return status;
 }
 
 static DisplayModePtr
 output_get_modes(xf86OutputPtr output)
 {
-    drmModeConnectorPtr drm_connector = output->driver_private;
+    struct output_private *priv = output->driver_private;
+    drmModeConnectorPtr drm_connector = priv->drm_connector;
     drmModeModeInfoPtr drm_mode = NULL;
     DisplayModePtr modes = NULL, mode = NULL;
     int i;
@@ -161,7 +184,10 @@ output_get_property(xf86OutputPtr output, Atom property)
 static void
 output_destroy(xf86OutputPtr output)
 {
-    drmModeFreeConnector(output->driver_private);
+    struct output_private *priv = output->driver_private;
+    drmModeFreeConnector(priv->drm_connector);
+    xfree(priv);
+    output->driver_private = NULL;
 }
 
 static const xf86OutputFuncsRec output_funcs = {
@@ -188,6 +214,7 @@ xorg_output_init(ScrnInfoPtr pScrn)
     drmModeResPtr res;
     drmModeConnectorPtr drm_connector = NULL;
     drmModeEncoderPtr drm_encoder = NULL;
+    struct output_private *priv;
     char name[32];
     int c, v, p;
 
@@ -226,9 +253,16 @@ xorg_output_init(ScrnInfoPtr pScrn)
                 drm_connector->connector_type_id);
 
 
+       priv = xcalloc(sizeof(*priv), 1);
+       if (!priv) {
+           continue;
+       }
+
        output = xf86OutputCreate(pScrn, &output_funcs, name);
-       if (!output)
+       if (!output) {
+           xfree(priv);
            continue;
+       }
 
        drm_encoder = drmModeGetEncoder(ms->fd, drm_connector->encoders[0]);
        if (drm_encoder) {
@@ -238,7 +272,9 @@ xorg_output_init(ScrnInfoPtr pScrn)
            output->possible_crtcs = 0;
            output->possible_clones = 0;
        }
-       output->driver_private = drm_connector;
+       priv->c = c;
+       priv->drm_connector = drm_connector;
+       output->driver_private = priv;
        output->subpixel_order = SubPixelHorizontalRGB;
        output->interlaceAllowed = FALSE;
        output->doubleScanAllowed = FALSE;
@@ -248,4 +284,11 @@ xorg_output_init(ScrnInfoPtr pScrn)
     drmModeFreeResources(res);
 }
 
+unsigned
+xorg_output_get_id(xf86OutputPtr output)
+{
+    struct output_private *priv = output->driver_private;
+    return priv->drm_connector->connector_id;
+}
+
 /* vim: set sw=4 ts=8 sts=4: */
index 583493116d50405b1b1af0d91586fd186166d63d..a9610a8678079c5e79517c5cae3f8806db97b8af 100644 (file)
@@ -7,7 +7,6 @@
 #include "util/u_draw_quad.h"
 #include "util/u_math.h"
 #include "util/u_memory.h"
-#include "util/u_rect.h"
 #include "util/u_sampler.h"
 #include "util/u_surface.h"
 
index cb6773424a827e7a0819057b19657cdccb2c685d..65fbc3234ba70a013cb5bb74c805342d62675b95 100644 (file)
@@ -96,8 +96,6 @@ typedef struct _modesettingRec
     /* Broken-out options. */
     OptionInfoPtr Options;
 
-    unsigned int SaveGeneration;
-
     void (*blockHandler)(int, pointer, pointer, pointer);
     struct pipe_fence_handle *fence[XORG_NR_FENCES];
 
@@ -192,6 +190,9 @@ xorg_crtc_cursor_destroy(xf86CrtcPtr crtc);
 void
 xorg_output_init(ScrnInfoPtr pScrn);
 
+unsigned
+xorg_output_get_id(xf86OutputPtr output);
+
 
 /***********************************************************************
  * xorg_xv.c
index f26ffb8ad4f4da5602eb5930ca324a84d2dd0f31..4f8641e056169dc004f3433e134b121dd587f831 100644 (file)
@@ -56,7 +56,7 @@ $(MKLIB) -o $@ -noprefix -linker '$(CC)' -ldflags '$(LDFLAGS)' \
        $(MKLIB_OPTIONS) $(EGL_DRIVER_OBJECTS) \
        -Wl,--start-group $($(1)_ST) $(EGL_DRIVER_PIPES) \
        $(GALLIUM_AUXILIARIES) -Wl,--end-group \
-       $($(1)_LIBS) $(EGL_DRIVER_LIBS)
+       $($(1)_LIBS) $(EGL_DRIVER_LIBS) -L$(TOP)/$(LIB_DIR) -l$(EGL_LIB)
 endef
 
 egl_x11_$(EGL_DRIVER_NAME).so: $(EGL_DRIVER_OBJECTS) $(x11_ST) $(EGL_DRIVER_PIPES) $(GALLIUM_AUXILIARIES) Makefile
index ca3e1ec1327051fc6e3cadd797832c4c7a307d62..9077cbf6a45b5400b083c303cd120e5c8b038a3a 100644 (file)
@@ -1,5 +1,8 @@
+import os
 Import('*')
        
+# Compatibility with old build scripts:
+#
 if 'xlib' in env['winsys']:
        SConscript([
                'libgl-xlib/SConscript',
@@ -10,12 +13,7 @@ if 'gdi' in env['winsys']:
                'libgl-gdi/SConscript',
        ])
 
-if env['platform'] == 'linux' and 'xlib' in env['winsys'] and 'graw-xlib' in env['winsys']:
-       SConscript([
-               'graw-xlib/SConscript',
-       ])
-else:
-    if not env['msvc']:
+if not 'graw-xlib' in env['targets'] and not env['msvc']:
         # XXX: disable until MSVC can link correctly
         SConscript('graw-null/SConscript')
 
@@ -30,3 +28,13 @@ if 'xorg' in env['statetrackers']:
                SConscript([
                        'xorg-vmwgfx/SConscript',
                ])
+
+# Ideally all non-target directories would produce convenience
+# libraries, and the actual shared libraries and other installables
+# would be finally assembled in the targets subtree:
+#
+for target in env['targets']:
+    SConscript(os.path.join(target, 'SConscript'))
+
+
+
index 293015bc6bccf42121a266c4d889b726bd96dc08..6965f5873e4ccf0d26f5e53fa6c1b71d3d3a6866 100644 (file)
@@ -18,8 +18,6 @@
 #include "sw/sw_public.h"
 #include "sw/sw.c"
 
-#include "state_tracker/graw.h"
-
 #include <stdio.h>
 
 
index ad84841922d1dae5ab0cc2121aaeb324e319f27f..40332fa4e147c6b12e70c83fafeb05dc6421c41a 100644 (file)
@@ -25,6 +25,7 @@ env.Append(CPPPATH = [
 
 sources = [
     'graw_xlib.c',
+    'graw_util.c',
 ]
 
 if True:
diff --git a/src/gallium/targets/graw-xlib/graw_util.c b/src/gallium/targets/graw-xlib/graw_util.c
new file mode 100644 (file)
index 0000000..147532c
--- /dev/null
@@ -0,0 +1,36 @@
+
+#include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
+#include "tgsi/tgsi_text.h"
+#include "util/u_memory.h"
+#include "state_tracker/graw.h"
+
+
+/* Helper functions.  These are the same for all graw implementations.
+ */
+void *graw_parse_vertex_shader(struct pipe_context *pipe,
+                               const char *text)
+{
+   struct tgsi_token tokens[1024];
+   struct pipe_shader_state state;
+
+   if (!tgsi_text_translate(text, tokens, Elements(tokens)))
+      return NULL;
+
+   state.tokens = tokens;
+   return pipe->create_vs_state(pipe, &state);
+}
+
+void *graw_parse_fragment_shader(struct pipe_context *pipe,
+                                 const char *text)
+{
+   struct tgsi_token tokens[1024];
+   struct pipe_shader_state state;
+
+   if (!tgsi_text_translate(text, tokens, Elements(tokens)))
+      return NULL;
+
+   state.tokens = tokens;
+   return pipe->create_fs_state(pipe, &state);
+}
+
index 21715c26fdc88af3c9f2cf60649b1f9008f9d35b..41120ba3c70f1b78ffba2eee73f9064fee811b69 100644 (file)
@@ -1,4 +1,5 @@
 #include "pipe/p_compiler.h"
+#include "pipe/p_context.h"
 #include "util/u_debug.h"
 #include "util/u_memory.h"
 #include "target-helpers/wrap_screen.h"
 
 static struct {
    Display *display;
+   void (*draw)(void);
 } graw;
 
 
-struct pipe_screen *
-graw_init( void )
+static struct pipe_screen *
+graw_create_screen( void )
 {
    const char *default_driver;
    const char *driver;
    struct pipe_screen *screen = NULL;
    struct sw_winsys *winsys = NULL;
 
-   graw.display = XOpenDisplay(NULL);
-   if (graw.display == NULL)
-      return NULL;
-
    /* Create the underlying winsys, which performs presents to Xlib
     * drawables:
     */
@@ -78,14 +76,16 @@ graw_init( void )
  
 
 
-void *
-graw_create_window( int x,
-                    int y,
-                    unsigned width,
-                    unsigned height,
-                    enum pipe_format format )
+struct pipe_screen *
+graw_create_window_and_screen( int x,
+                               int y,
+                               unsigned width,
+                               unsigned height,
+                               enum pipe_format format,
+                               void **handle)
 {
-   struct xlib_drawable *handle = NULL;
+   struct pipe_screen *screen = NULL;
+   struct xlib_drawable *xlib_handle = NULL;
    XSetWindowAttributes attr;
    Window root;
    Window win = 0;
@@ -94,6 +94,9 @@ graw_create_window( int x,
    int n;
    int scrnum;
 
+   graw.display = XOpenDisplay(NULL);
+   if (graw.display == NULL)
+      return NULL;
 
    scrnum = DefaultScreen( graw.display );
    root = RootWindow( graw.display, scrnum );
@@ -105,8 +108,8 @@ graw_create_window( int x,
    if (graw.display == NULL)
       goto fail;
 
-   handle = CALLOC_STRUCT(xlib_drawable);
-   if (handle == NULL)
+   xlib_handle = CALLOC_STRUCT(xlib_drawable);
+   if (xlib_handle == NULL)
       goto fail;
 
 
@@ -148,7 +151,6 @@ graw_create_window( int x,
                               None, (char **)NULL, 0, &sizehints);
    }
 
-   XFree(visinfo);
    XMapWindow(graw.display, win);
    while (1) {
       XEvent e;
@@ -158,14 +160,27 @@ graw_create_window( int x,
       }
    }
    
-   handle->visual = visinfo->visual;
-   handle->drawable = (Drawable)win;
-   handle->depth = visinfo->depth;
-   return (void *)handle;
+   xlib_handle->visual = visinfo->visual;
+   xlib_handle->drawable = (Drawable)win;
+   xlib_handle->depth = visinfo->depth;
+   *handle = (void *)xlib_handle;
+
+   screen = graw_create_screen();
+   if (screen == NULL)
+      goto fail;
 
-fail:
-   FREE(handle);
    XFree(visinfo);
+   return screen;
+
+fail:
+   if (screen)
+      screen->destroy(screen);
+
+   if (xlib_handle)
+      FREE(xlib_handle);
+
+   if (visinfo)
+      XFree(visinfo);
 
    if (win)
       XDestroyWindow(graw.display, win);
@@ -174,8 +189,19 @@ fail:
 }
 
 
+void 
+graw_set_display_func( void (*draw)( void ) )
+{
+   graw.draw = draw;
+}
+
 void
-graw_destroy_window( void *xlib_drawable )
+graw_main_loop( void )
 {
+   int i;
+   for (i = 0; i < 10; i++) {
+      graw.draw();
+      sleep(1);
+   }
 }
 
index 8a92ac2c499dba96168da0070dd2f34404d75f71..7eab973db314e6fc99b2fa4c29dc5008fc1387fa 100644 (file)
@@ -12,7 +12,9 @@ env.Prepend(LIBPATH = [graw.dir])
 env.Prepend(LIBS = ['graw'])
 
 progs = [
-    'clear'
+    'clear',
+    'tri',
+    'quad-tex',
 ]
 
 for prog in progs:
index 84dd7807337629872bd7848923418d7712397139..28c986eee64df5c0e5307a2d5257c57cea08673d 100644 (file)
@@ -20,33 +20,58 @@ enum pipe_format formats[] = {
 static const int WIDTH = 300;
 static const int HEIGHT = 300;
 
-int main( int argc, char *argv[] )
+struct pipe_screen *screen;
+struct pipe_context *ctx;
+struct pipe_surface *surf;
+static void *window = NULL;
+
+static void draw( void )
+{
+   float clear_color[4] = {1,0,1,1};
+
+   ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
+   ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+#if 0
+   /* At the moment, libgraw leaks out/makes available some of the
+    * symbols from gallium/auxiliary, including these debug helpers.
+    * Will eventually want to bless some of these paths, and lock the
+    * others down so they aren't accessible from test programs.
+    *
+    * This currently just happens to work on debug builds - a release
+    * build will probably fail to link here:
+    */
+   debug_dump_surface_bmp(ctx, "result.bmp", surf);
+#endif
+
+   screen->flush_frontbuffer(screen, surf, window);
+}
+
+static void init( void )
 {
-   struct pipe_screen *screen;
-   struct pipe_context *pipe;
-   struct pipe_surface *surf;
    struct pipe_framebuffer_state fb;
    struct pipe_resource *tex, templat;
-   void *window = NULL;
-   float clear_color[4] = {1,0,1,1};
    int i;
 
-   screen = graw_init();
-   if (screen == NULL)
-      exit(1);
-
+   /* It's hard to say whether window or screen should be created
+    * first.  Different environments would prefer one or the other.
+    *
+    * Also, no easy way of querying supported formats if the screen
+    * cannot be created first.
+    */
    for (i = 0; 
         window == NULL && formats[i] != PIPE_FORMAT_NONE;
         i++) {
       
-      window = graw_create_window(0,0,300,300, formats[i]);
+      screen = graw_create_window_and_screen(0,0,300,300,
+                                             formats[i],
+                                             &window);
    }
-   
    if (window == NULL)
       exit(2);
    
-   pipe = screen->context_create(screen, NULL);
-   if (pipe == NULL)
+   ctx = screen->context_create(screen, NULL);
+   if (ctx == NULL)
       exit(3);
 
    templat.target = PIPE_TEXTURE_2D;
@@ -57,10 +82,10 @@ int main( int argc, char *argv[] )
    templat.last_level = 0;
    templat.nr_samples = 1;
    templat.bind = (PIPE_BIND_RENDER_TARGET |
-                        PIPE_BIND_DISPLAY_TARGET);
+                   PIPE_BIND_DISPLAY_TARGET);
    
    tex = screen->resource_create(screen,
-                                &templat);
+                                 &templat);
    if (tex == NULL)
       exit(4);
 
@@ -76,21 +101,16 @@ int main( int argc, char *argv[] )
    fb.height = HEIGHT;
    fb.cbufs[0] = surf;
 
-   pipe->set_framebuffer_state(pipe, &fb);
-   pipe->clear(pipe, PIPE_CLEAR_COLOR, clear_color, 0, 0);
-   pipe->flush(pipe, PIPE_FLUSH_RENDER_CACHE, NULL);
+   ctx->set_framebuffer_state(ctx, &fb);
+}
 
-   /* At the moment, libgraw includes/makes available all the symbols
-    * from gallium/auxiliary, including these debug helpers.  Will
-    * eventually want to bless some of these paths, and lock the
-    * others down so they aren't accessible from test programs.
-    */
-   if (0)
-      debug_dump_surface_bmp(pipe, "result.bmp", surf);
 
-   screen->flush_frontbuffer(screen, surf, window);
 
-   os_time_sleep(100*1000*100);
+int main( int argc, char *argv[] )
+{
+   init();
 
+   graw_set_display_func( draw );
+   graw_main_loop();
    return 0;
 }
diff --git a/src/gallium/tests/graw/quad-tex.c b/src/gallium/tests/graw/quad-tex.c
new file mode 100644 (file)
index 0000000..91b1cf4
--- /dev/null
@@ -0,0 +1,404 @@
+/* Display a cleared blue window.  This demo has no dependencies on
+ * any utility code, just the graw interface and gallium.
+ */
+
+#include "state_tracker/graw.h"
+#include "pipe/p_screen.h"
+#include "pipe/p_context.h"
+#include "pipe/p_shader_tokens.h"
+#include "pipe/p_state.h"
+#include "pipe/p_defines.h"
+#include <unistd.h>             /* for sleep() */
+
+#include "util/u_debug.h"       /* debug_dump_surface_bmp() */
+#include "util/u_inlines.h"
+#include "util/u_memory.h"      /* Offset() */
+#include "util/u_box.h"    
+
+enum pipe_format formats[] = {
+   PIPE_FORMAT_R8G8B8A8_UNORM,
+   PIPE_FORMAT_B8G8R8A8_UNORM,
+   PIPE_FORMAT_NONE
+};
+
+static const int WIDTH = 300;
+static const int HEIGHT = 300;
+
+static struct pipe_screen *screen = NULL;
+static struct pipe_context *ctx = NULL;
+static struct pipe_resource *rttex = NULL;
+static struct pipe_resource *samptex = NULL;
+static struct pipe_surface *surf = NULL;
+static struct pipe_sampler_view *sv = NULL;
+static void *sampler = NULL;
+static void *window = NULL;
+
+struct vertex {
+   float position[4];
+   float color[4];
+};
+
+static struct vertex vertices[] =
+{
+   { { 0.9, -0.9, 0.0, 1.0 },
+     { 1, 0, 0, 1 } },
+
+   { { 0.9,  0.9, 0.0, 1.0 },
+     { 1, 1, 0, 1 } },
+
+   { {-0.9,  0.9, 0.0, 1.0 },
+     { 0, 1, 0, 1 } },
+
+   { {-0.9,  -0.9, 0.0, 1.0 },
+     { 0, 0, 0, 1 } },
+};
+
+
+
+
+static void set_viewport( float x, float y,
+                          float width, float height,
+                          float near, float far)
+{
+   float z = far;
+   float half_width = (float)width / 2.0f;
+   float half_height = (float)height / 2.0f;
+   float half_depth = ((float)far - (float)near) / 2.0f;
+   struct pipe_viewport_state vp;
+
+   vp.scale[0] = half_width;
+   vp.scale[1] = half_height;
+   vp.scale[2] = half_depth;
+   vp.scale[3] = 1.0f;
+
+   vp.translate[0] = half_width + x;
+   vp.translate[1] = half_height + y;
+   vp.translate[2] = half_depth + z;
+   vp.translate[3] = 0.0f;
+
+   ctx->set_viewport_state( ctx, &vp );
+}
+
+static void set_vertices( void )
+{
+   struct pipe_vertex_element ve[2];
+   struct pipe_vertex_buffer vbuf;
+   void *handle;
+
+   memset(ve, 0, sizeof ve);
+
+   ve[0].src_offset = Offset(struct vertex, position);
+   ve[0].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+   ve[1].src_offset = Offset(struct vertex, color);
+   ve[1].src_format = PIPE_FORMAT_R32G32B32A32_FLOAT;
+
+   handle = ctx->create_vertex_elements_state(ctx, 2, ve);
+   ctx->bind_vertex_elements_state(ctx, handle);
+
+
+   vbuf.stride = sizeof( struct vertex );
+   vbuf.max_index = sizeof(vertices) / vbuf.stride;
+   vbuf.buffer_offset = 0;
+   vbuf.buffer = screen->user_buffer_create(screen,
+                                            vertices,
+                                            sizeof(vertices),
+                                            PIPE_BIND_VERTEX_BUFFER);
+
+   ctx->set_vertex_buffers(ctx, 1, &vbuf);
+}
+
+static void set_vertex_shader( void )
+{
+   void *handle;
+   const char *text =
+      "VERT\n"
+      "DCL IN[0]\n"
+      "DCL IN[1]\n"
+      "DCL OUT[0], POSITION\n"
+      "DCL OUT[1], GENERIC[0]\n"
+      "  0: MOV OUT[1], IN[1]\n"
+      "  1: MOV OUT[0], IN[0]\n"
+      "  2: END\n";
+
+   handle = graw_parse_vertex_shader(ctx, text);
+   ctx->bind_vs_state(ctx, handle);
+}
+
+static void set_fragment_shader( void )
+{
+   void *handle;
+   const char *text =
+      "FRAG\n"
+      "DCL IN[0], GENERIC[0], PERSPECTIVE\n"
+      "DCL OUT[0], COLOR\n"
+      "DCL TEMP[0]\n"
+      "DCL SAMP[0]\n"
+      "  0: TXP TEMP[0], IN[0], SAMP[0], 2D\n"
+      "  1: MOV OUT[0], TEMP[0]\n"
+      "  2: END\n";
+
+   handle = graw_parse_fragment_shader(ctx, text);
+   ctx->bind_fs_state(ctx, handle);
+}
+
+
+static void draw( void )
+{
+   float clear_color[4] = {.5,.5,.5,1};
+
+   ctx->clear(ctx, PIPE_CLEAR_COLOR, clear_color, 0, 0);
+   ctx->draw_arrays(ctx, PIPE_PRIM_QUADS, 0, 4);
+   ctx->flush(ctx, PIPE_FLUSH_RENDER_CACHE, NULL);
+
+#if 0
+   /* At the moment, libgraw leaks out/makes available some of the
+    * symbols from gallium/auxiliary, including these debug helpers.
+    * Will eventually want to bless some of these paths, and lock the
+    * others down so they aren't accessible from test programs.
+    *
+    * This currently just happens to work on debug builds - a release
+    * build will probably fail to link here:
+    */
+   debug_dump_surface_bmp(ctx, "result.bmp", surf);
+#endif
+
+   screen->flush_frontbuffer(screen, surf, window);
+}
+
+#define SIZE 16
+
+static void init_tex( void )
+{ 
+   struct pipe_sampler_view sv_template;
+   struct pipe_sampler_state sampler_desc;
+   struct pipe_resource templat;
+   struct pipe_box box;
+   ubyte tex2d[SIZE][SIZE][4];
+   int s, t;
+
+#if (SIZE != 2)
+   for (s = 0; s < SIZE; s++) {
+      for (t = 0; t < SIZE; t++) {
+         if (0) {
+            int x = (s ^ t) & 1;
+           tex2d[t][s][0] = (x) ? 0 : 63;
+           tex2d[t][s][1] = (x) ? 0 : 128;
+           tex2d[t][s][2] = 0;
+           tex2d[t][s][3] = 0xff;
+         }
+         else {
+            int x = ((s ^ t) >> 2) & 1;
+           tex2d[t][s][0] = s*255/(SIZE-1);
+           tex2d[t][s][1] = t*255/(SIZE-1);
+           tex2d[t][s][2] = (x) ? 0 : 128;
+           tex2d[t][s][3] = 0xff;
+         }
+      }
+   }
+#else
+   tex2d[0][0][0] = 0;
+   tex2d[0][0][1] = 255;
+   tex2d[0][0][2] = 255;
+   tex2d[0][0][3] = 0;
+
+   tex2d[0][1][0] = 0;
+   tex2d[0][1][1] = 0;
+   tex2d[0][1][2] = 255;
+   tex2d[0][1][3] = 255;
+
+   tex2d[1][0][0] = 255;
+   tex2d[1][0][1] = 255;
+   tex2d[1][0][2] = 0;
+   tex2d[1][0][3] = 255;
+
+   tex2d[1][1][0] = 255;
+   tex2d[1][1][1] = 0;
+   tex2d[1][1][2] = 0;
+   tex2d[1][1][3] = 255;
+#endif
+
+   templat.target = PIPE_TEXTURE_2D;
+   templat.format = PIPE_FORMAT_B8G8R8A8_UNORM;
+   templat.width0 = SIZE;
+   templat.height0 = SIZE;
+   templat.depth0 = 1;
+   templat.last_level = 0;
+   templat.nr_samples = 1;
+   templat.bind = PIPE_BIND_SAMPLER_VIEW;
+
+   
+   samptex = screen->resource_create(screen,
+                                 &templat);
+   if (samptex == NULL)
+      exit(4);
+
+   u_box_2d(0,0,SIZE,SIZE, &box);
+
+   ctx->transfer_inline_write(ctx,
+                              samptex,
+                              u_subresource(0,0),
+                              PIPE_TRANSFER_WRITE,
+                              &box,
+                              tex2d,
+                              sizeof tex2d[0],
+                              sizeof tex2d);
+
+   /* Possibly read back & compare against original data:
+    */
+   if (0)
+   {
+      struct pipe_transfer *t;
+      uint32_t *ptr;
+      t = pipe_get_transfer(ctx, samptex,
+                            0, 0, 0, /* face, level, zslice */
+                            PIPE_TRANSFER_READ,
+                            0, 0, SIZE, SIZE); /* x, y, width, height */
+
+      ptr = ctx->transfer_map(ctx, t);
+
+      if (memcmp(ptr, tex2d, sizeof tex2d) != 0) {
+         assert(0);
+         exit(9);
+      }
+
+      ctx->transfer_unmap(ctx, t);
+
+      ctx->transfer_destroy(ctx, t);
+   }
+
+   memset(&sv_template, 0, sizeof sv_template);
+   sv_template.format = samptex->format;
+   sv_template.texture = samptex;
+   sv_template.first_level = 0;
+   sv_template.last_level = 0;
+   sv_template.swizzle_r = 0;
+   sv_template.swizzle_g = 1;
+   sv_template.swizzle_b = 2;
+   sv_template.swizzle_a = 3;
+   sv = ctx->create_sampler_view(ctx, samptex, &sv_template);
+   if (sv == NULL)
+      exit(5);
+
+   ctx->set_fragment_sampler_views(ctx, 1, &sv);
+   
+
+   memset(&sampler_desc, 0, sizeof sampler_desc);
+   sampler_desc.wrap_s = PIPE_TEX_WRAP_REPEAT;
+   sampler_desc.wrap_t = PIPE_TEX_WRAP_REPEAT;
+   sampler_desc.wrap_r = PIPE_TEX_WRAP_REPEAT;
+   sampler_desc.min_img_filter = PIPE_TEX_FILTER_NEAREST;
+   sampler_desc.min_mip_filter = PIPE_TEX_MIPFILTER_NONE;
+   sampler_desc.mag_img_filter = PIPE_TEX_FILTER_NEAREST;
+   sampler_desc.compare_mode = PIPE_TEX_COMPARE_NONE;
+   sampler_desc.compare_func = 0;
+   sampler_desc.normalized_coords = 1;
+   sampler_desc.max_anisotropy = 0;
+   
+   sampler = ctx->create_sampler_state(ctx, &sampler_desc);
+   if (sampler == NULL)
+      exit(6);
+
+   ctx->bind_fragment_sampler_states(ctx, 1, &sampler);
+   
+}
+
+static void init( void )
+{
+   struct pipe_framebuffer_state fb;
+   struct pipe_resource templat;
+   int i;
+
+   /* It's hard to say whether window or screen should be created
+    * first.  Different environments would prefer one or the other.
+    *
+    * Also, no easy way of querying supported formats if the screen
+    * cannot be created first.
+    */
+   for (i = 0; 
+        window == NULL && formats[i] != PIPE_FORMAT_NONE;
+        i++) {
+      
+      screen = graw_create_window_and_screen(0,0,300,300,
+                                             formats[i],
+                                             &window);
+   }
+   
+   ctx = screen->context_create(screen, NULL);
+   if (ctx == NULL)
+      exit(3);
+
+   templat.target = PIPE_TEXTURE_2D;
+   templat.format = formats[i];
+   templat.width0 = WIDTH;
+   templat.height0 = HEIGHT;
+   templat.depth0 = 1;
+   templat.last_level = 0;
+   templat.nr_samples = 1;
+   templat.bind = (PIPE_BIND_RENDER_TARGET |
+                   PIPE_BIND_DISPLAY_TARGET);
+   
+   rttex = screen->resource_create(screen,
+                                 &templat);
+   if (rttex == NULL)
+      exit(4);
+
+   surf = screen->get_tex_surface(screen, rttex, 0, 0, 0,
+                                  PIPE_BIND_RENDER_TARGET |
+                                  PIPE_BIND_DISPLAY_TARGET);
+   if (surf == NULL)
+      exit(5);
+
+   memset(&fb, 0, sizeof fb);
+   fb.nr_cbufs = 1;
+   fb.width = WIDTH;
+   fb.height = HEIGHT;
+   fb.cbufs[0] = surf;
+
+   ctx->set_framebuffer_state(ctx, &fb);
+   
+   {
+      struct pipe_blend_state blend;
+      void *handle;
+      memset(&blend, 0, sizeof blend);
+      blend.rt[0].colormask = PIPE_MASK_RGBA;
+      handle = ctx->create_blend_state(ctx, &blend);
+      ctx->bind_blend_state(ctx, handle);
+   }
+
+   {
+      struct pipe_depth_stencil_alpha_state depthstencil;
+      void *handle;
+      memset(&depthstencil, 0, sizeof depthstencil);
+      handle = ctx->create_depth_stencil_alpha_state(ctx, &depthstencil);
+      ctx->bind_depth_stencil_alpha_state(ctx, handle);
+   }
+
+   {
+      struct pipe_rasterizer_state rasterizer;
+      void *handle;
+      memset(&rasterizer, 0, sizeof rasterizer);
+      rasterizer.front_winding = PIPE_WINDING_CW;
+      rasterizer.cull_mode = PIPE_WINDING_NONE;
+      rasterizer.gl_rasterization_rules = 1;
+      handle = ctx->create_rasterizer_state(ctx, &rasterizer);
+      ctx->bind_rasterizer_state(ctx, handle);
+   }
+
+   set_viewport(0, 0, WIDTH, HEIGHT, 30, 1000);
+
+   init_tex();
+
+   set_vertices();
+   set_vertex_shader();
+   set_fragment_shader();
+}
+
+
+int main( int argc, char *argv[] )
+{
+   init();
+
+   graw_set_display_func( draw );
+   graw_main_loop();
+   return 0;
+}
index b48b6358e01a4dec2000805ba5d1155dcf3bf84f..b9ecf9ded071e9c80265f2ad93e16cb701297642 100644 (file)
@@ -88,4 +88,7 @@ boolean radeon_drm_bufmgr_get_handle(struct pb_buffer *_buf,
 
 boolean radeon_drm_bufmgr_is_buffer_referenced(struct pb_buffer *_buf,
                                                enum r300_reference_domain domain);
+
+void radeon_drm_bufmgr_wait(struct pb_buffer *_buf);
+
 #endif
index b8366498922803844b3d895e23242e8caf5e1ee1..a05205da8861fc4e76290e5ebcae62cbdac8be18 100644 (file)
@@ -419,3 +419,10 @@ void radeon_drm_bufmgr_flush_maps(struct pb_manager *_mgr)
 
     make_empty_list(&mgr->buffer_map_list);
 }
+
+void radeon_drm_bufmgr_wait(struct pb_buffer *_buf)
+{
+    struct radeon_drm_buffer *buf = get_drm_buffer(_buf);
+
+    radeon_bo_wait(buf->bo);
+}
index 94cd5281e268c29aaee77cb255e2a9e8218bc3f1..e188f7e7ccd50271f34300c7dadb2c73ebc4d96f 100644 (file)
@@ -98,6 +98,13 @@ static void radeon_r300_winsys_buffer_unmap(struct r300_winsys_screen *ws,
     pb_unmap(_buf);
 }
 
+static void radeon_r300_winsys_buffer_wait(struct r300_winsys_screen *ws,
+                                           struct r300_winsys_buffer *buf)
+{
+    struct pb_buffer *_buf = radeon_pb_buffer(buf);
+    radeon_drm_bufmgr_wait(_buf);
+}
+
 static void radeon_r300_winsys_buffer_reference(struct r300_winsys_screen *rws,
                                                struct r300_winsys_buffer **pdst,
                                                struct r300_winsys_buffer *src)
@@ -343,6 +350,7 @@ radeon_setup_winsys(int fd, struct radeon_libdrm_winsys* ws)
     ws->base.buffer_get_tiling = radeon_r300_winsys_buffer_get_tiling;
     ws->base.buffer_map = radeon_r300_winsys_buffer_map;
     ws->base.buffer_unmap = radeon_r300_winsys_buffer_unmap;
+    ws->base.buffer_wait = radeon_r300_winsys_buffer_wait;
     ws->base.buffer_reference = radeon_r300_winsys_buffer_reference;
     ws->base.buffer_from_handle = radeon_r300_winsys_buffer_from_handle;
     ws->base.buffer_get_handle = radeon_r300_winsys_buffer_get_handle;
index d4d4270eb864ab91b9522715de823e8218c77dc4..b997abda9b0724dd8f394d79fd844b55893f5ed9 100644 (file)
@@ -145,6 +145,7 @@ wsw_dt_create(struct sw_winsys *ws,
     * XXX Why don't we just get the template.
     */
    memset(&templ, 0, sizeof(templ));
+   templ.target = PIPE_TEXTURE_2D;
    templ.width0 = width;
    templ.height0 = height;
    templ.format = format;
@@ -175,6 +176,18 @@ wsw_dt_from_handle(struct sw_winsys *ws,
    return wsw_dt_wrap_texture(wsw, tex, stride);
 }
 
+static boolean
+wsw_dt_get_handle(struct sw_winsys *ws,
+                  struct sw_displaytarget *dt,
+                  struct winsys_handle *whandle)
+{
+   struct wrapper_sw_winsys *wsw = wrapper_sw_winsys(ws);
+   struct wrapper_sw_displaytarget *wdt = wrapper_sw_displaytarget(dt);
+   struct pipe_resource *tex = wdt->tex;
+
+   return wsw->screen->resource_get_handle(wsw->screen, tex, whandle);
+}
+
 static void *
 wsw_dt_map(struct sw_winsys *ws,
            struct sw_displaytarget *dt,
@@ -267,6 +280,7 @@ wrapper_sw_winsys_warp_pipe_screen(struct pipe_screen *screen)
 
    wsw->base.displaytarget_create = wsw_dt_create;
    wsw->base.displaytarget_from_handle = wsw_dt_from_handle;
+   wsw->base.displaytarget_get_handle = wsw_dt_get_handle;
    wsw->base.displaytarget_map = wsw_dt_map;
    wsw->base.displaytarget_unmap = wsw_dt_unmap;
    wsw->base.displaytarget_destroy = wsw_dt_destroy;
index eafb87c359730954e0949bc6fbd96ba50b0d6695..45959915b4b40c69259e182cf6242d9a27ff9294 100644 (file)
@@ -361,6 +361,14 @@ dri2WaitGL(__GLXDRIdrawable * pdraw)
 static void
 dri2FlushFrontBuffer(__DRIdrawable *driDrawable, void *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.drawable);
+
    dri2WaitGL(loaderPrivate);
 }
 
@@ -421,16 +429,16 @@ 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->drawable);
+
     /* Old servers can't handle swapbuffers */
     if (!pdp->swapAvailable) {
        dri2CopySubBuffer(pdraw, 0, 0, priv->width, priv->height);
        return 0;
     }
 
-    /* Old servers don't send invalidate events */
-    if (!pdp->invalidateAvailable)
-       dri2InvalidateBuffers(dpyPriv->dpy, pdraw->drawable);
-
 #ifdef X_DRI2SwapBuffers
     DRI2SwapBuffers(pdraw->psc->dpy, pdraw->xDrawable, target_msc, divisor,
                    remainder, &ret);
@@ -737,10 +745,9 @@ dri2CreateDisplay(Display * dpy)
    pdp->loader_extensions[i++] = &systemTimeExtension.base;
 
 #ifdef __DRI_USE_INVALIDATE
-   if (pdp->invalidateAvailable)
-      pdp->loader_extensions[i++] = &dri2UseInvalidate.base;
-   pdp->loader_extensions[i++] = NULL;
+   pdp->loader_extensions[i++] = &dri2UseInvalidate.base;
 #endif
+   pdp->loader_extensions[i++] = NULL;
 
    return &pdp->base;
 }
index 73be93e941a65cf6e6878ae769460ec766cae8eb..576ac5afdc30d463cd09bc13560601b953729890 100644 (file)
@@ -106,7 +106,7 @@ pcedit = \
 
 pcedit-es1 = \
        $(pcedit) \
-       -e 's,@GLESv1_CM_REQ_PRIV@,$(GLESv1_CM_REQ_PRIV),' \
+       -e 's,@GLESv1_CM_PC_REQ_PRIV@,$(GLESv1_CM_PC_REQ_PRIV),' \
        -e 's,@GLESv1_CM_PC_LIB_PRIV@,$(GLESv1_CM_PC_LIB_PRIV),' \
        -e 's,@GLESv1_CM_PC_CFLAGS@,$(GLESv1_CM_PC_CFLAGS),' \
        -e 's,@GLESv1_CM_LIB@,$(GLESv1_CM_LIB),'
index 029a16500b54cb7ee7c3470fd212e04e099cf554..49ef859e456126767e5592f03633d10765fced2a 100644 (file)
@@ -42,7 +42,6 @@
 #include "brw_state.h"
 #include "brw_clip.h"
 
-
 #define FRONT_UNFILLED_BIT  0x1
 #define BACK_UNFILLED_BIT   0x2
 
@@ -127,6 +126,14 @@ static void compile_clip_prog( struct brw_context *brw,
     */
    program = brw_get_program(&c.func, &program_size);
 
+    if (INTEL_DEBUG & DEBUG_CLIP) {
+      printf("clip:\n");
+      for (i = 0; i < program_size / sizeof(struct brw_instruction); i++)
+        brw_disasm(stdout, &((struct brw_instruction *)program)[i],
+                   intel->gen);
+      printf("\n");
+    }
+
    /* Upload
     */
    dri_bo_unreference(brw->clip.prog_bo);
index d71bac7f617512fceb6bdc37a55aea96ae55f9e9..68222c6c278ff84d6fbdaaee2989ae731a5f2824 100644 (file)
@@ -114,8 +114,6 @@ struct brw_clip_compile {
 
    GLboolean need_direction;
 
-   GLuint last_mrf;
-
    GLuint header_position_offset;
    GLuint offset[VERT_ATTRIB_MAX];
 };
index b27fe654ca9e6ccb3dbeffdb3e59c7da456cd911..916a99ea004e5871c63a3f2cbc3aa4bf9aa73b94 100644 (file)
@@ -177,7 +177,7 @@ void brw_clip_tri_init_vertices( struct brw_clip_compile *c )
 void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
 {
    struct brw_compile *p = &c->func;
-   struct brw_instruction *is_poly;
+   struct brw_instruction *is_poly, *is_trifan;
    struct brw_reg tmp0 = c->reg.loopcount; /* handy temporary */
 
    brw_AND(p, tmp0, get_element_ud(c->reg.R0, 2), brw_imm_ud(PRIM_MASK)); 
@@ -195,8 +195,22 @@ void brw_clip_tri_flat_shade( struct brw_clip_compile *c )
    is_poly = brw_ELSE(p, is_poly);
    {
       if (c->key.pv_first) {
-         brw_clip_copy_colors(c, 1, 0);
-         brw_clip_copy_colors(c, 2, 0);
+        brw_CMP(p,
+                vec1(brw_null_reg()),
+                BRW_CONDITIONAL_EQ,
+                tmp0,
+                brw_imm_ud(_3DPRIM_TRIFAN));
+        is_trifan = brw_IF(p, BRW_EXECUTE_1);
+        {
+           brw_clip_copy_colors(c, 0, 1);
+           brw_clip_copy_colors(c, 2, 1);
+        }
+        is_trifan = brw_ELSE(p, is_trifan);
+        {
+           brw_clip_copy_colors(c, 1, 0);
+           brw_clip_copy_colors(c, 2, 0);
+        }
+        brw_ENDIF(p, is_trifan);
       }
       else {
          brw_clip_copy_colors(c, 0, 2);
index 34a966a47a224d4f751a1eb754190f171dcf6115..2148bc8244a70539e4a3a7011f5916b75881d239 100644 (file)
@@ -211,27 +211,14 @@ void brw_clip_emit_vue(struct brw_clip_compile *c,
                       GLuint header)
 {
    struct brw_compile *p = &c->func;
-   GLuint start = c->last_mrf;
 
    brw_clip_ff_sync(c);
 
    assert(!(allocate && eot));
-   
-   /* Cycle through mrf regs - probably futile as we have to wait for
-    * the allocation response anyway.  Also, the order this function
-    * is invoked doesn't correspond to the order the instructions will
-    * be executed, so it won't have any effect in many cases.
-    */
-#if 0
-   if (start + c->nr_regs + 1 >= MAX_MRF)
-      start = 0;
 
-   c->last_mrf = start + c->nr_regs + 1;
-#endif
-       
    /* Copy the vertex from vertn into m1..mN+1:
     */
-   brw_copy_from_indirect(p, brw_message_reg(start+1), vert, c->nr_regs);
+   brw_copy_from_indirect(p, brw_message_reg(1), vert, c->nr_regs);
 
    /* Overwrite PrimType and PrimStart in the message header, for
     * each vertex in turn:
@@ -247,7 +234,7 @@ void brw_clip_emit_vue(struct brw_clip_compile *c,
     */
    brw_urb_WRITE(p, 
                 allocate ? c->reg.R0 : retype(brw_null_reg(), BRW_REGISTER_TYPE_UD),
-                start,
+                0,
                 c->reg.R0,
                 allocate,
                 1,             /* used */
@@ -370,18 +357,13 @@ void brw_clip_ff_sync(struct brw_clip_compile *c)
         need_ff_sync = brw_IF(p, BRW_EXECUTE_1);
         {
             brw_OR(p, c->reg.ff_sync, c->reg.ff_sync, brw_imm_ud(0x1));
-            brw_ff_sync(p, 
-                    c->reg.R0,
-                    0,
-                    c->reg.R0,
-                    1, 
-                    1,         /* used */
-                    1,         /* msg length */
-                    1,         /* response length */
-                    0,         /* eot */
-                    1,         /* write compelete */
-                    0,         /* urb offset */
-                    BRW_URB_SWIZZLE_NONE);
+            brw_ff_sync(p,
+                       c->reg.R0,
+                       0,
+                       c->reg.R0,
+                       1, /* allocate */
+                       1, /* response length */
+                       0 /* eot */);
         }
         brw_ENDIF(p, need_ff_sync);
         brw_set_predicate_control(p, BRW_PREDICATE_NONE);
index 6b04ad9ec6ab21cef3d2a03fa7c95a7952cec8e7..dc4bd5802d4ccd126cc4a69552c3a9dc380726ac 100644 (file)
@@ -192,8 +192,6 @@ GLboolean brwCreateContext( int api,
    ctx->VertexProgram._MaintainTnlProgram = GL_TRUE;
    ctx->FragmentProgram._MaintainTexEnvProgram = GL_TRUE;
 
-   make_empty_list(&brw->query.active_head);
-
    brw_draw_init( brw );
 
    return GL_TRUE;
index 1f09651126b436518e7d4c7fb09c2d91c292d5a1..a97fcb0f4db8d84808be202940c81bf7f518c50a 100644 (file)
@@ -418,18 +418,12 @@ struct brw_vertex_info {
 struct brw_query_object {
    struct gl_query_object Base;
 
-   /** Doubly linked list of active query objects in the context. */
-   struct brw_query_object *prev, *next;
-
    /** Last query BO associated with this query. */
    dri_bo *bo;
    /** First index in bo with query data for this object. */
    int first_index;
    /** Last index in bo with query data for this object. */
    int last_index;
-
-   /* Total count of pixels from previous BOs */
-   unsigned int count;
 };
 
 
@@ -664,7 +658,7 @@ struct brw_context
    } cc;
 
    struct {
-      struct brw_query_object active_head;
+      struct brw_query_object *obj;
       dri_bo *bo;
       int index;
       GLboolean active;
@@ -726,7 +720,7 @@ void brw_upload_urb_fence(struct brw_context *brw);
 void brw_upload_cs_urb_state(struct brw_context *brw);
 
 /* brw_disasm.c */
-int brw_disasm (FILE *file, struct brw_instruction *inst);
+int brw_disasm (FILE *file, struct brw_instruction *inst, int gen);
 
 /*======================================================================
  * Inline conversion functions.  These are better-typed than the
index f26a13fc3c37aaaf19c21a2f23a35411b4f9851d..2d3556b80546cf4ae857840cd5ed0860c2edc4ba 100644 (file)
 #define CMD_BINDING_TABLE_PTRS        0x7801
 # define GEN6_BINDING_TABLE_MODIFY_VS  (1 << 8)
 # define GEN6_BINDING_TABLE_MODIFY_GS  (1 << 9)
-# define GEN6_BINDING_TABLE_MODIFY_PS  (1 << 10)
+# define GEN6_BINDING_TABLE_MODIFY_PS  (1 << 12)
 
 #define CMD_3D_SAMPLER_STATE_POINTERS                  0x7802 /* SNB+ */
 # define PS_SAMPLER_STATE_CHANGE                               (1 << 12)
index db3fc50a63b5e4ca43220d44690746550550047a..ff12daf497d296dbce6e8a00152de90446a12680 100644 (file)
@@ -323,6 +323,11 @@ char *math_precision[2] = {
     [1] = "partial_precision"
 };
 
+char *urb_opcode[2] = {
+    [0] = "urb_write",
+    [1] = "ff_sync",
+};
+
 char *urb_swizzle[4] = {
     [BRW_URB_SWIZZLE_NONE] = "",
     [BRW_URB_SWIZZLE_INTERLEAVE] = "interleave",
@@ -774,7 +779,7 @@ static int src1 (FILE *file, struct brw_instruction *inst)
     }
 }
 
-int brw_disasm (FILE *file, struct brw_instruction *inst)
+int brw_disasm (FILE *file, struct brw_instruction *inst, int gen)
 {
     int        err = 0;
     int space = 0;
@@ -829,12 +834,20 @@ int brw_disasm (FILE *file, struct brw_instruction *inst)
     }
 
     if (inst->header.opcode == BRW_OPCODE_SEND) {
+       int target;
+
+       if (gen >= 5)
+          target = inst->bits2.send_gen5.sfid;
+       else
+          target = inst->bits3.generic.msg_target;
+
        newline (file);
        pad (file, 16);
        space = 0;
        err |= control (file, "target function", target_function,
-                       inst->bits3.generic.msg_target, &space);
-       switch (inst->bits3.generic.msg_target) {
+                       target, &space);
+
+       switch (target) {
        case BRW_MESSAGE_TARGET_MATH:
            err |= control (file, "math function", math_function,
                            inst->bits3.math.function, &space);
@@ -864,8 +877,17 @@ int brw_disasm (FILE *file, struct brw_instruction *inst)
                    inst->bits3.dp_write.send_commit_msg);
            break;
        case BRW_MESSAGE_TARGET_URB:
-           format (file, " %d", inst->bits3.urb.offset);
+           if (gen >= 5) {
+               format (file, " %d", inst->bits3.urb_gen5.offset);
+           } else {
+               format (file, " %d", inst->bits3.urb.offset);
+           }
+
            space = 1;
+           if (gen >= 5) {
+               err |= control (file, "urb opcode", urb_opcode,
+                               inst->bits3.urb_gen5.opcode, &space);
+           }
            err |= control (file, "urb swizzle", urb_swizzle,
                            inst->bits3.urb.swizzle_control, &space);
            err |= control (file, "urb allocate", urb_allocate,
index 8247faa36d8d082e891b91d57895ce3446433d58..9cbff24863d0adbd5192ac97b0d0745b93c1afc9 100644 (file)
@@ -59,7 +59,7 @@ static GLuint half_float_types[5] = {
    0,
    BRW_SURFACEFORMAT_R16_FLOAT,
    BRW_SURFACEFORMAT_R16G16_FLOAT,
-   0, /* can't seem to render this one */
+   BRW_SURFACEFORMAT_R16G16B16A16_FLOAT,
    BRW_SURFACEFORMAT_R16G16B16A16_FLOAT
 };
 
index 4f55158e8f38287a62672550aae44d27085a9e45..3a32ad26c12aa1f3b7181028796cdb5ff9d94544 100644 (file)
@@ -822,13 +822,8 @@ void brw_ff_sync(struct brw_compile *p,
                   GLuint msg_reg_nr,
                   struct brw_reg src0,
                   GLboolean allocate,
-                  GLboolean used,
-                  GLuint msg_length,
                   GLuint response_length,
-                  GLboolean eot,
-                  GLboolean writes_complete,
-                  GLuint offset,
-                  GLuint swizzle);
+                  GLboolean eot);
 
 void brw_fb_WRITE(struct brw_compile *p,
                   struct brw_reg dest,
index 785d382a009d8f7e772ba6106cf8a790e8bbe057..175899b026863c7d2c3913d2ae081d5671ed1441 100644 (file)
@@ -280,28 +280,23 @@ static void brw_set_math_message( struct brw_context *brw,
 }
 
 
-static void brw_set_ff_sync_message( struct brw_context *brw,
-                                struct brw_instruction *insn,
-                                GLboolean allocate,
-                                GLboolean used,
-                                GLuint msg_length,
-                                GLuint response_length,
-                                GLboolean end_of_thread,
-                                GLboolean complete,
-                                GLuint offset,
-                                GLuint swizzle_control )
+static void brw_set_ff_sync_message(struct brw_context *brw,
+                                   struct brw_instruction *insn,
+                                   GLboolean allocate,
+                                   GLuint response_length,
+                                   GLboolean end_of_thread)
 {
        brw_set_src1(insn, brw_imm_d(0));
 
-       insn->bits3.urb_gen5.opcode = 1;
-       insn->bits3.urb_gen5.offset = offset;
-       insn->bits3.urb_gen5.swizzle_control = swizzle_control;
+       insn->bits3.urb_gen5.opcode = 1; /* FF_SYNC */
+       insn->bits3.urb_gen5.offset = 0; /* Not used by FF_SYNC */
+       insn->bits3.urb_gen5.swizzle_control = 0; /* Not used by FF_SYNC */
        insn->bits3.urb_gen5.allocate = allocate;
-       insn->bits3.urb_gen5.used = used;
-       insn->bits3.urb_gen5.complete = complete;
+       insn->bits3.urb_gen5.used = 0; /* Not used by FF_SYNC */
+       insn->bits3.urb_gen5.complete = 0; /* Not used by FF_SYNC */
        insn->bits3.urb_gen5.header_present = 1;
-       insn->bits3.urb_gen5.response_length = response_length;
-       insn->bits3.urb_gen5.msg_length = msg_length;
+       insn->bits3.urb_gen5.response_length = response_length; /* may be 1 or 0 */
+       insn->bits3.urb_gen5.msg_length = 1;
        insn->bits3.urb_gen5.end_of_thread = end_of_thread;
        insn->bits2.send_gen5.sfid = BRW_MESSAGE_TARGET_URB;
        insn->bits2.send_gen5.end_of_thread = end_of_thread;
@@ -1451,18 +1446,11 @@ void brw_ff_sync(struct brw_compile *p,
                   GLuint msg_reg_nr,
                   struct brw_reg src0,
                   GLboolean allocate,
-                  GLboolean used,
-                  GLuint msg_length,
                   GLuint response_length,
-                  GLboolean eot,
-                  GLboolean writes_complete,
-                  GLuint offset,
-                  GLuint swizzle)
+                  GLboolean eot)
 {
    struct brw_instruction *insn = next_insn(p, BRW_OPCODE_SEND);
 
-   assert(msg_length < 16);
-
    brw_set_dest(insn, dest);
    brw_set_src0(insn, src0);
    brw_set_src1(insn, brw_imm_d(0));
@@ -1470,13 +1458,8 @@ void brw_ff_sync(struct brw_compile *p,
    insn->header.destreg__conditionalmod = msg_reg_nr;
 
    brw_set_ff_sync_message(p->brw,
-                      insn,
-                      allocate,
-                      used,
-                      msg_length,
-                      response_length, 
-                      eot, 
-                      writes_complete, 
-                      offset,
-                      swizzle);
+                          insn,
+                          allocate,
+                          response_length,
+                          eot);
 }
index 4b13494ecf901ac0ad1ca71f2b56ddafa8dbe60c..94d93f3aa65bca5a4eb962ee9de8262e94ee2e0a 100644 (file)
@@ -122,6 +122,16 @@ static void compile_gs_prog( struct brw_context *brw,
     */
    program = brw_get_program(&c.func, &program_size);
 
+    if (INTEL_DEBUG & DEBUG_GS) {
+       int i;
+
+      printf("gs:\n");
+      for (i = 0; i < program_size / sizeof(struct brw_instruction); i++)
+        brw_disasm(stdout, &((struct brw_instruction *)program)[i],
+                   intel->gen);
+      printf("\n");
+    }
+
    /* Upload
     */
    dri_bo_unreference(brw->gs.prog_bo);
@@ -163,6 +173,12 @@ static void populate_key( struct brw_context *brw,
    
    /* _NEW_LIGHT */
    key->pv_first = (ctx->Light.ProvokingVertex == GL_FIRST_VERTEX_CONVENTION);
+   if (key->primitive == GL_QUADS && ctx->Light.ShadeModel != GL_FLAT) {
+      /* Provide consistent primitive order with brw_set_prim's
+       * optimization of single quads to trifans.
+       */
+      key->pv_first = GL_TRUE;
+   }
 
    key->need_gs_prog = (key->hint_gs_always ||
                        brw->primitive == GL_QUADS ||
index dd7b057d62025046d0ea9e161a83653992059233..99a6f6be113aa935e2fc822528d27ed9ac85dbc5 100644 (file)
@@ -104,18 +104,13 @@ static void brw_gs_ff_sync(struct brw_gs_compile *c, int num_prim)
 {
        struct brw_compile *p = &c->func;
        brw_MOV(p, get_element_ud(c->reg.R0, 1), brw_imm_ud(num_prim));
-       brw_ff_sync(p, 
-                               c->reg.R0,
-                               0,
-                               c->reg.R0,
-                               1,      
-                               1,              /* used */
-                               1,      /* msg length */
-                               1,              /* response length */
-                               0,              /* eot */
-                               1,              /* write compelete */
-                               0,              /* urb offset */
-                               BRW_URB_SWIZZLE_NONE);
+       brw_ff_sync(p,
+                   c->reg.R0,
+                   0,
+                   c->reg.R0,
+                   1, /* allocate */
+                   1, /* response length */
+                   0 /* eot */);
 }
 
 
index 6cce7e50890b0af6ed1adbb7f79a3788b7f37d81..3f47a68049fd299d04bbe7db78e152c2c04b8de8 100644 (file)
@@ -38,7 +38,6 @@
  * required for handling queries, so that we can be sure that we won't
  * have to emit a batchbuffer without getting the ending PS_DEPTH_COUNT.
  */
-#include "main/simple_list.h"
 #include "main/imports.h"
 
 #include "brw_context.h"
@@ -105,7 +104,7 @@ brw_begin_query(GLcontext *ctx, struct gl_query_object *q)
    query->first_index = -1;
    query->last_index = -1;
 
-   insert_at_head(&brw->query.active_head, query);
+   brw->query.obj = query;
    intel->stats_wm++;
 }
 
@@ -131,7 +130,7 @@ brw_end_query(GLcontext *ctx, struct gl_query_object *q)
       brw->query.bo = NULL;
    }
 
-   remove_from_list(query);
+   brw->query.obj = NULL;
 
    intel->stats_wm--;
 }
@@ -161,7 +160,7 @@ brw_prepare_query_begin(struct brw_context *brw)
    struct intel_context *intel = &brw->intel;
 
    /* Skip if we're not doing any queries. */
-   if (is_empty_list(&brw->query.active_head))
+   if (!brw->query.obj)
       return;
 
    /* Get a new query BO if we're going to need it. */
@@ -182,10 +181,10 @@ void
 brw_emit_query_begin(struct brw_context *brw)
 {
    struct intel_context *intel = &brw->intel;
-   struct brw_query_object *query;
+   struct brw_query_object *query = brw->query.obj;
 
    /* Skip if we're not doing any queries, or we've emitted the start. */
-   if (brw->query.active || is_empty_list(&brw->query.active_head))
+   if (!query || brw->query.active)
       return;
 
    BEGIN_BATCH(4);
@@ -205,16 +204,14 @@ brw_emit_query_begin(struct brw_context *brw)
    OUT_BATCH(0);
    ADVANCE_BATCH();
 
-   foreach(query, &brw->query.active_head) {
-      if (query->bo != brw->query.bo) {
-        if (query->bo != NULL)
-           brw_queryobj_get_results(query);
-        dri_bo_reference(brw->query.bo);
-        query->bo = brw->query.bo;
-        query->first_index = brw->query.index;
-      }
-      query->last_index = brw->query.index;
+   if (query->bo != brw->query.bo) {
+      if (query->bo != NULL)
+        brw_queryobj_get_results(query);
+      dri_bo_reference(brw->query.bo);
+      query->bo = brw->query.bo;
+      query->first_index = brw->query.index;
    }
+   query->last_index = brw->query.index;
    brw->query.active = GL_TRUE;
 }
 
index 57d1c29ade11cd0f5608dc0417ac5f776396d833..b0dd1ff3afb5d670a10d6ec523bac48a208087c5 100644 (file)
@@ -46,6 +46,7 @@
 static void compile_sf_prog( struct brw_context *brw,
                             struct brw_sf_prog_key *key )
 {
+   struct intel_context *intel = &brw->intel;
    struct brw_sf_compile c;
    const GLuint *program;
    GLuint program_size;
@@ -107,6 +108,14 @@ static void compile_sf_prog( struct brw_context *brw,
     */
    program = brw_get_program(&c.func, &program_size);
 
+   if (INTEL_DEBUG & DEBUG_SF) {
+      printf("sf:\n");
+      for (i = 0; i < program_size / sizeof(struct brw_instruction); i++)
+        brw_disasm(stdout, &((struct brw_instruction *)program)[i],
+                   intel->gen);
+      printf("\n");
+   }
+
    /* Upload
     */
    dri_bo_unreference(brw->sf.prog_bo);
@@ -154,6 +163,7 @@ static void upload_sf_prog(struct brw_context *brw)
       break;
    }
 
+   /* _NEW_POINT */
    key.do_point_sprite = ctx->Point.PointSprite;
    if (key.do_point_sprite) {
       int i;
index 44b085e214b8654e0b37c2a24c259afa0508c0ca..57ffb2d89e029476a48735e715b58b4e115781d0 100644 (file)
@@ -48,6 +48,7 @@ static void do_vs_prog( struct brw_context *brw,
    const GLuint *program;
    struct brw_vs_compile c;
    int aux_size;
+   int i;
 
    memset(&c, 0, sizeof(c));
    memcpy(&c.key, key, sizeof(*key));
@@ -63,6 +64,17 @@ static void do_vs_prog( struct brw_context *brw,
       c.prog_data.inputs_read |= 1<<VERT_ATTRIB_EDGEFLAG;
    }
 
+   /* Put dummy slots into the VUE for the SF to put the replaced
+    * point sprite coords in.  We shouldn't need these dummy slots,
+    * which take up precious URB space, but it would mean that the SF
+    * doesn't get nice aligned pairs of input coords into output
+    * coords, which would be a pain to handle.
+    */
+   for (i = 0; i < 8; i++) {
+      if (c.key.point_coord_replace & (1 << i))
+        c.prog_data.outputs_written |= BITFIELD64_BIT(VERT_RESULT_TEX0 + i);
+   }
+
    if (0)
       _mesa_print_program(&c.vp->program.Base);
 
@@ -106,6 +118,7 @@ static void brw_upload_vs_prog(struct brw_context *brw)
    struct brw_vs_prog_key key;
    struct brw_vertex_program *vp = 
       (struct brw_vertex_program *)brw->vertex_program;
+   int i;
 
    memset(&key, 0, sizeof(key));
 
@@ -117,6 +130,14 @@ static void brw_upload_vs_prog(struct brw_context *brw)
    key.copy_edgeflag = (ctx->Polygon.FrontMode != GL_FILL ||
                        ctx->Polygon.BackMode != GL_FILL);
 
+   /* _NEW_POINT */
+   if (ctx->Point.PointSprite) {
+      for (i = 0; i < 8; i++) {
+        if (ctx->Point.CoordReplace[i])
+           key.point_coord_replace |= (1 << i);
+      }
+   }
+
    /* Make an early check for the key.
     */
    dri_bo_unreference(brw->vs.prog_bo);
@@ -135,7 +156,7 @@ static void brw_upload_vs_prog(struct brw_context *brw)
  */
 const struct brw_tracked_state brw_vs_prog = {
    .dirty = {
-      .mesa  = _NEW_TRANSFORM | _NEW_POLYGON,
+      .mesa  = _NEW_TRANSFORM | _NEW_POLYGON | _NEW_POINT,
       .brw   = BRW_NEW_VERTEX_PROGRAM,
       .cache = 0
    },
index 95e0501b1ebb3262bfb12936401aa56040b4b0cc..6493744f3eb486a17f2473c659a1dc7bfc95427c 100644 (file)
@@ -43,7 +43,7 @@ struct brw_vs_prog_key {
    GLuint program_string_id;
    GLuint nr_userclip:4;
    GLuint copy_edgeflag:1;
-   GLuint pad:26;
+   GLuint point_coord_replace:8;
 };
 
 
index dc6ab81c4acc3a7967c6d09358b744d290e47ef7..0b44deeb634f2beb37e21c92aa7de5c454f66b64 100644 (file)
@@ -1882,7 +1882,7 @@ void brw_vs_emit(struct brw_vs_compile *c )
 
       printf("vs-native:\n");
       for (i = 0; i < p->nr_insn; i++)
-        brw_disasm(stderr, &p->store[i]);
+        brw_disasm(stderr, &p->store[i], intel->gen);
       printf("\n");
    }
 }
index 375e7953912389ab580249d86295278ee2b7d284..323cfac8fa7851872a6888cf744775dd427c5f08 100644 (file)
@@ -1717,7 +1717,7 @@ void brw_wm_emit( struct brw_wm_compile *c )
 
       printf("wm-native:\n");
       for (i = 0; i < p->nr_insn; i++)
-        brw_disasm(stderr, &p->store[i]);
+        brw_disasm(stderr, &p->store[i], p->brw->intel.gen);
       printf("\n");
    }
 }
index 88b885cb94147bc981e4f66ffc471a1c943f3052..fe3c89b7212c82617c1ecb130540dab660c5a7c1 100644 (file)
@@ -2111,7 +2111,7 @@ static void brw_wm_emit_glsl(struct brw_context *brw, struct brw_wm_compile *c)
     if (INTEL_DEBUG & DEBUG_WM) {
       printf("wm-native:\n");
       for (i = 0; i < p->nr_insn; i++)
-        brw_disasm(stderr, &p->store[i]);
+        brw_disasm(stderr, &p->store[i], intel->gen);
       printf("\n");
     }
 }
index 9768b0deee77891b062ef3aae47377cce4a26b05..ca8e34483685dcf6992741371845ddaa23cffe48 100644 (file)
@@ -130,8 +130,7 @@ _intel_batchbuffer_flush(struct intel_batchbuffer *batch, const char *file,
    struct intel_context *intel = batch->intel;
    GLuint used = batch->ptr - batch->map;
 
-   if (!intel->using_dri2_swapbuffers &&
-       intel->first_post_swapbuffers_batch == NULL) {
+   if (intel->first_post_swapbuffers_batch == NULL) {
       intel->first_post_swapbuffers_batch = intel->batch->buf;
       drm_intel_bo_reference(intel->first_post_swapbuffers_batch);
    }
index 7d9f302dca6a2a33cb412a7276095ab90d870d0c..a590c799ad3a0b75315afd3db1f0e8e4c77f7ec1 100644 (file)
@@ -353,6 +353,9 @@ intelClearWithBlit(GLcontext *ctx, GLbitfield mask)
       OUT_BATCH(clear_val);
       ADVANCE_BATCH();
 
+      if (intel->always_flush_cache)
+        intel_batchbuffer_emit_mi_flush(intel->batch);
+
       if (buf == BUFFER_DEPTH || buf == BUFFER_STENCIL)
         mask &= ~(BUFFER_BIT_DEPTH | BUFFER_BIT_STENCIL);
       else
index 0369942b39eb66597b811b283089a2baa13c2674..05d49986546727381de55163066e33bfc7343071 100644 (file)
@@ -440,6 +440,28 @@ intel_prepare_render(struct intel_context *intel)
     */
    if (intel->is_front_buffer_rendering)
       intel->front_buffer_dirty = GL_TRUE;
+
+   /* Wait for the swapbuffers before the one we just emitted, so we
+    * don't get too many swaps outstanding for apps that are GPU-heavy
+    * but not CPU-heavy.
+    *
+    * We're using intelDRI2Flush (called from the loader before
+    * swapbuffer) and glFlush (for front buffer rendering) as the
+    * indicator that a frame is done and then throttle when we get
+    * here as we prepare to render the next frame.  At this point for
+    * round trips for swap/copy and getting new buffers are done and
+    * we'll spend less time waiting on the GPU.
+    *
+    * Unfortunately, we don't have a handle to the batch containing
+    * the swap, and getting our hands on that doesn't seem worth it,
+    * so we just us the first batch we emitted after the last swap.
+    */
+   if (intel->need_throttle && intel->first_post_swapbuffers_batch) {
+      drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
+      drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
+      intel->first_post_swapbuffers_batch = NULL;
+      intel->need_throttle = GL_FALSE;
+   }
 }
 
 static void
@@ -451,8 +473,7 @@ intel_viewport(GLcontext *ctx, GLint x, GLint y, GLsizei w, GLsizei h)
     if (intel->saved_viewport)
        intel->saved_viewport(ctx, x, y, w, h);
 
-    if (!intel->using_dri2_swapbuffers &&
-       !intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
+    if (!intel->meta.internal_viewport_call && ctx->DrawBuffer->Name == 0) {
        dri2InvalidateDrawable(driContext->driDrawablePriv);
        dri2InvalidateDrawable(driContext->driReadablePriv);
     }
@@ -471,12 +492,12 @@ static const struct dri_debug_control debug_control[] = {
    { "buf",   DEBUG_BUFMGR},
    { "reg",   DEBUG_REGION},
    { "fbo",   DEBUG_FBO},
-   { "lock",  DEBUG_LOCK},
+   { "gs",    DEBUG_GS},
    { "sync",  DEBUG_SYNC},
    { "prim",  DEBUG_PRIMS },
    { "vert",  DEBUG_VERTS },
    { "dri",   DEBUG_DRI },
-   { "dma",   DEBUG_DMA },
+   { "sf",    DEBUG_SF },
    { "san",   DEBUG_SANITY },
    { "sleep", DEBUG_SLEEP },
    { "stats", DEBUG_STATS },
@@ -487,6 +508,7 @@ static const struct dri_debug_control debug_control[] = {
    { "glsl_force", DEBUG_GLSL_FORCE },
    { "urb",   DEBUG_URB },
    { "vs",    DEBUG_VS },
+   { "clip",  DEBUG_CLIP },
    { NULL,    0 }
 };
 
@@ -529,27 +551,8 @@ intel_glFlush(GLcontext *ctx)
    struct intel_context *intel = intel_context(ctx);
 
    intel_flush(ctx);
-
    intel_flush_front(ctx);
-
-   /* We're using glFlush as an indicator that a frame is done, which is
-    * what DRI2 does before calling SwapBuffers (and means we should catch
-    * people doing front-buffer rendering, as well)..
-    *
-    * Wait for the swapbuffers before the one we just emitted, so we don't
-    * get too many swaps outstanding for apps that are GPU-heavy but not
-    * CPU-heavy.
-    *
-    * Unfortunately, we don't have a handle to the batch containing the swap,
-    * and getting our hands on that doesn't seem worth it, so we just us the
-    * first batch we emitted after the last swap.
-    */
-   if (!intel->using_dri2_swapbuffers &&
-       intel->first_post_swapbuffers_batch != NULL) {
-      drm_intel_bo_wait_rendering(intel->first_post_swapbuffers_batch);
-      drm_intel_bo_unreference(intel->first_post_swapbuffers_batch);
-      intel->first_post_swapbuffers_batch = NULL;
-   }
+   intel->need_throttle = GL_TRUE;
 }
 
 void
@@ -905,6 +908,12 @@ intelMakeCurrent(__DRIcontext * driContextPriv,
       driContextPriv->dri2.read_stamp = driReadPriv->dri2.stamp - 1;
       intel_prepare_render(intel);
       _mesa_make_current(&intel->ctx, fb, readFb);
+
+      /* We do this in intel_prepare_render() too, but intel->ctx.DrawBuffer
+       * is NULL at that point.  We can't call _mesa_makecurrent()
+       * first, since we need the buffer size for the initial
+       * viewport.  So just call intel_draw_buffer() again here. */
+      intel_draw_buffer(&intel->ctx, intel->ctx.DrawBuffer);
    }
    else {
       _mesa_make_current(NULL, NULL, NULL);
index db244e587293569075289fe01c7fb3d97226f29d..04d5fc92a251af35ac14dcefef0d1bf58dbcb038 100644 (file)
@@ -150,8 +150,8 @@ struct intel_context
 
    struct intel_batchbuffer *batch;
    drm_intel_bo *first_post_swapbuffers_batch;
+   GLboolean need_throttle;
    GLboolean no_batch_wrap;
-   GLboolean using_dri2_swapbuffers;
 
    struct
    {
@@ -326,12 +326,12 @@ extern int INTEL_DEBUG;
 #define DEBUG_BUFMGR    0x200
 #define DEBUG_REGION    0x400
 #define DEBUG_FBO       0x800
-#define DEBUG_LOCK      0x1000
+#define DEBUG_GS        0x1000
 #define DEBUG_SYNC     0x2000
 #define DEBUG_PRIMS    0x4000
 #define DEBUG_VERTS    0x8000
 #define DEBUG_DRI       0x10000
-#define DEBUG_DMA       0x20000
+#define DEBUG_SF        0x20000
 #define DEBUG_SANITY    0x40000
 #define DEBUG_SLEEP     0x80000
 #define DEBUG_STATS     0x100000
@@ -341,6 +341,7 @@ extern int INTEL_DEBUG;
 #define DEBUG_URB       0x1000000
 #define DEBUG_VS        0x2000000
 #define DEBUG_GLSL_FORCE 0x4000000
+#define DEBUG_CLIP      0x8000000
 
 #define DBG(...) do {                                          \
        if (INTEL_DEBUG & FILE_DEBUG_FLAG)                      \
index 3aed253e2407aa2a7b435ab4970386aec5bf7279..15a465c6402ae9b4bdb47a565251d554fd55e1fb 100644 (file)
@@ -110,23 +110,16 @@ intelDRI2Flush(__DRIdrawable *drawable)
    if (intel->gen < 4)
       INTEL_FIREVERTICES(intel);
 
+   intel->need_throttle = GL_TRUE;
+
    if (intel->batch->map != intel->batch->ptr)
       intel_batchbuffer_flush(intel->batch);
 }
 
-static void
-intelDRI2Invalidate(__DRIdrawable *drawable)
-{
-   struct intel_context *intel = drawable->driContextPriv->driverPrivate;
-
-   intel->using_dri2_swapbuffers = GL_TRUE;
-   dri2InvalidateDrawable(drawable);
-}
-
 static const struct __DRI2flushExtensionRec intelFlushExtension = {
     { __DRI2_FLUSH, __DRI2_FLUSH_VERSION },
     intelDRI2Flush,
-    intelDRI2Invalidate,
+    dri2InvalidateDrawable,
 };
 
 static __DRIimage *
index 7be5231eaef1ab5611be7c0d0e5b9e8e7e394e49..610a169beb2d7e7fb0c8838aafc0cbba3b6f0848 100644 (file)
@@ -1,7 +1,7 @@
 #include "intel_context.h"
 #include "intel_tex.h"
 #include "main/enums.h"
-
+#include "main/formats.h"
 
 /**
  * Choose hardware texture format given the user's glTexImage parameters.
@@ -208,22 +208,11 @@ intelChooseTextureFormat(GLcontext * ctx, GLint internalFormat,
 
 int intel_compressed_num_bytes(GLuint mesaFormat)
 {
-   int bytes = 0;
-   switch(mesaFormat) {
-     
-   case MESA_FORMAT_RGB_FXT1:
-   case MESA_FORMAT_RGBA_FXT1:
-   case MESA_FORMAT_RGB_DXT1:
-   case MESA_FORMAT_RGBA_DXT1:
-     bytes = 2;
-     break;
-     
-   case MESA_FORMAT_RGBA_DXT3:
-   case MESA_FORMAT_RGBA_DXT5:
-     bytes = 4;
-   default:
-     break;
-   }
-   
-   return bytes;
+   GLuint bw, bh;
+   GLuint block_size;
+
+   block_size = _mesa_get_format_bytes(mesaFormat);
+   _mesa_get_format_block_size(mesaFormat, &bw, &bh);
+
+   return block_size / bh;
 }
index e432afc3d41eaf002f0c5a09fb334e09d295d8f4..34d22b45591117f00751ce53910e2d77f2104f59 100644 (file)
@@ -21,6 +21,7 @@ C_SOURCES = \
                radeon_dataflow.c \
                radeon_dataflow_deadcode.c \
                radeon_dataflow_swizzles.c \
+               radeon_optimize.c \
                r3xx_fragprog.c \
                r300_fragprog.c \
                r300_fragprog_swizzle.c \
index cfa48a59e3aadbd2d39b000c5f40dfe720b6e72f..5d5de2f1b2ab03186453fa346d3189b126574846 100644 (file)
@@ -56,7 +56,8 @@ static const struct swizzle_data native_swizzles[] = {
        {MAKE_SWZ3(Z, X, Y), R300_ALU_ARGC_SRC0C_ZXY, 1},
        {MAKE_SWZ3(W, Z, Y), R300_ALU_ARGC_SRC0CA_WZY, 1},
        {MAKE_SWZ3(ONE, ONE, ONE), R300_ALU_ARGC_ONE, 0},
-       {MAKE_SWZ3(ZERO, ZERO, ZERO), R300_ALU_ARGC_ZERO, 0}
+       {MAKE_SWZ3(ZERO, ZERO, ZERO), R300_ALU_ARGC_ZERO, 0},
+       {MAKE_SWZ3(HALF, HALF, HALF), R300_ALU_ARGC_HALF, 0}
 };
 
 static const int num_native_swizzles = sizeof(native_swizzles)/sizeof(native_swizzles[0]);
@@ -221,6 +222,7 @@ unsigned int r300FPTranslateAlphaSwizzle(unsigned int src, unsigned int swizzle)
        case RC_SWIZZLE_W: return R300_ALU_ARGA_SRC0A + src;
        case RC_SWIZZLE_ONE: return R300_ALU_ARGA_ONE;
        case RC_SWIZZLE_ZERO: return R300_ALU_ARGA_ZERO;
+       case RC_SWIZZLE_HALF: return R300_ALU_ARGA_HALF;
        default: return R300_ALU_ARGA_ONE;
        }
 }
index 25bf373b6fde682c7211785790f307c21eeec016..3e88ccbc46de9c8ef791d196bc22f2d302b8214a 100644 (file)
@@ -152,6 +152,10 @@ void r3xx_compile_fragment_program(struct r300_fragment_program_compiler* c)
 
        debug_program_log(c, "after deadcode");
 
+       rc_optimize(&c->Base);
+
+       debug_program_log(c, "after dataflow optimize");
+
        rc_dataflow_swizzles(&c->Base);
        if (c->Base.Error)
                return;
index 16e2f3a218143ff19b97ee611c2509d7cc0c9424..0e6c62541fa46f39bee641fef2d965f745fbe290 100644 (file)
@@ -30,7 +30,7 @@
 #include "radeon_program.h"
 
 
-static void reads_normal(struct rc_instruction * fullinst, rc_read_write_fn cb, void * userdata)
+static void reads_normal(struct rc_instruction * fullinst, rc_read_write_chan_fn cb, void * userdata)
 {
        struct rc_sub_instruction * inst = &fullinst->U.I;
        const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
@@ -46,18 +46,15 @@ static void reads_normal(struct rc_instruction * fullinst, rc_read_write_fn cb,
 
                refmask &= RC_MASK_XYZW;
 
-               for(unsigned int chan = 0; chan < 4; ++chan) {
-                       if (GET_BIT(refmask, chan)) {
-                               cb(userdata, fullinst, inst->SrcReg[src].File, inst->SrcReg[src].Index, chan);
-                       }
-               }
+               if (refmask)
+                       cb(userdata, fullinst, inst->SrcReg[src].File, inst->SrcReg[src].Index, refmask);
 
                if (refmask && inst->SrcReg[src].RelAddr)
                        cb(userdata, fullinst, RC_FILE_ADDRESS, 0, RC_MASK_X);
        }
 }
 
-static void reads_pair(struct rc_instruction * fullinst,  rc_read_write_fn cb, void * userdata)
+static void reads_pair(struct rc_instruction * fullinst,  rc_read_write_mask_fn cb, void * userdata)
 {
        struct rc_pair_instruction * inst = &fullinst->U.P;
        unsigned int refmasks[3] = { 0, 0, 0 };
@@ -84,27 +81,23 @@ static void reads_pair(struct rc_instruction * fullinst,  rc_read_write_fn cb, v
        }
 
        for(unsigned int src = 0; src < 3; ++src) {
-               if (inst->RGB.Src[src].Used) {
-                       for(unsigned int chan = 0; chan < 3; ++chan) {
-                               if (GET_BIT(refmasks[src], chan))
-                                       cb(userdata, fullinst, inst->RGB.Src[src].File, inst->RGB.Src[src].Index, chan);
-                       }
-               }
+               if (inst->RGB.Src[src].Used && (refmasks[src] & RC_MASK_XYZ))
+                       cb(userdata, fullinst, inst->RGB.Src[src].File, inst->RGB.Src[src].Index,
+                          refmasks[src] & RC_MASK_XYZ);
 
-               if (inst->Alpha.Src[src].Used) {
-                       if (GET_BIT(refmasks[src], 3))
-                               cb(userdata, fullinst, inst->Alpha.Src[src].File, inst->Alpha.Src[src].Index, 3);
-               }
+               if (inst->Alpha.Src[src].Used && (refmasks[src] & RC_MASK_W))
+                       cb(userdata, fullinst, inst->Alpha.Src[src].File, inst->Alpha.Src[src].Index, RC_MASK_W);
        }
 }
 
 /**
- * Calls a callback function for all sourced register channels.
+ * Calls a callback function for all register reads.
  *
- * This is conservative, i.e. channels may be called multiple times,
- * and the writemask of the instruction is not taken into account.
+ * This is conservative, i.e. if the same register is referenced multiple times,
+ * the callback may also be called multiple times.
+ * Also, the writemask of the instruction is not taken into account.
  */
-void rc_for_all_reads(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata)
+void rc_for_all_reads_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata)
 {
        if (inst->Type == RC_INSTRUCTION_NORMAL) {
                reads_normal(inst, cb, userdata);
@@ -115,44 +108,39 @@ void rc_for_all_reads(struct rc_instruction * inst, rc_read_write_fn cb, void *
 
 
 
-static void writes_normal(struct rc_instruction * fullinst, rc_read_write_fn cb, void * userdata)
+static void writes_normal(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata)
 {
        struct rc_sub_instruction * inst = &fullinst->U.I;
        const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->Opcode);
 
-       if (opcode->HasDstReg) {
-               for(unsigned int chan = 0; chan < 4; ++chan) {
-                       if (GET_BIT(inst->DstReg.WriteMask, chan))
-                               cb(userdata, fullinst, inst->DstReg.File, inst->DstReg.Index, chan);
-               }
-       }
+       if (opcode->HasDstReg && inst->DstReg.WriteMask)
+               cb(userdata, fullinst, inst->DstReg.File, inst->DstReg.Index, inst->DstReg.WriteMask);
 
        if (inst->WriteALUResult)
-               cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, 0);
+               cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, RC_MASK_X);
 }
 
-static void writes_pair(struct rc_instruction * fullinst, rc_read_write_fn cb, void * userdata)
+static void writes_pair(struct rc_instruction * fullinst, rc_read_write_mask_fn cb, void * userdata)
 {
        struct rc_pair_instruction * inst = &fullinst->U.P;
 
-       for(unsigned int chan = 0; chan < 3; ++chan) {
-               if (GET_BIT(inst->RGB.WriteMask, chan))
-                       cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->RGB.DestIndex, chan);
-       }
+       if (inst->RGB.WriteMask)
+               cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->RGB.DestIndex, inst->RGB.WriteMask);
 
        if (inst->Alpha.WriteMask)
-               cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->Alpha.DestIndex, 3);
+               cb(userdata, fullinst, RC_FILE_TEMPORARY, inst->Alpha.DestIndex, RC_MASK_W);
 
        if (inst->WriteALUResult)
-               cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, 0);
+               cb(userdata, fullinst, RC_FILE_SPECIAL, RC_SPECIAL_ALU_RESULT, RC_MASK_X);
 }
 
 /**
- * Calls a callback function for all written register channels.
+ * Calls a callback function for all register writes in the instruction,
+ * reporting writemasks to the callback function.
  *
  * \warning Does not report output registers for paired instructions!
  */
-void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata)
+void rc_for_all_writes_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata)
 {
        if (inst->Type == RC_INSTRUCTION_NORMAL) {
                writes_normal(inst, cb, userdata);
@@ -162,6 +150,48 @@ void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void *
 }
 
 
+struct mask_to_chan_data {
+       void * UserData;
+       rc_read_write_chan_fn Fn;
+};
+
+static void mask_to_chan_cb(void * data, struct rc_instruction * inst,
+               rc_register_file file, unsigned int index, unsigned int mask)
+{
+       struct mask_to_chan_data * d = data;
+       for(unsigned int chan = 0; chan < 4; ++chan) {
+               if (GET_BIT(mask, chan))
+                       d->Fn(d->UserData, inst, file, index, chan);
+       }
+}
+
+/**
+ * Calls a callback function for all sourced register channels.
+ *
+ * This is conservative, i.e. channels may be called multiple times,
+ * and the writemask of the instruction is not taken into account.
+ */
+void rc_for_all_reads_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata)
+{
+       struct mask_to_chan_data d;
+       d.UserData = userdata;
+       d.Fn = cb;
+       rc_for_all_reads_mask(inst, &mask_to_chan_cb, &d);
+}
+
+/**
+ * Calls a callback function for all written register channels.
+ *
+ * \warning Does not report output registers for paired instructions!
+ */
+void rc_for_all_writes_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata)
+{
+       struct mask_to_chan_data d;
+       d.UserData = userdata;
+       d.Fn = cb;
+       rc_for_all_writes_mask(inst, &mask_to_chan_cb, &d);
+}
+
 static void remap_normal_instruction(struct rc_instruction * fullinst,
                rc_remap_register_fn cb, void * userdata)
 {
index 62cda20eea686c67ee251f9c6d397ef06e4dad6e..60a6e192a9f7371aebcd8f34b74883065e28f34b 100644 (file)
@@ -39,10 +39,15 @@ struct rc_swizzle_caps;
  * Help analyze and modify the register accesses of instructions.
  */
 /*@{*/
-typedef void (*rc_read_write_fn)(void * userdata, struct rc_instruction * inst,
+typedef void (*rc_read_write_chan_fn)(void * userdata, struct rc_instruction * inst,
                        rc_register_file file, unsigned int index, unsigned int chan);
-void rc_for_all_reads(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata);
-void rc_for_all_writes(struct rc_instruction * inst, rc_read_write_fn cb, void * userdata);
+void rc_for_all_reads_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata);
+void rc_for_all_writes_chan(struct rc_instruction * inst, rc_read_write_chan_fn cb, void * userdata);
+
+typedef void (*rc_read_write_mask_fn)(void * userdata, struct rc_instruction * inst,
+                       rc_register_file file, unsigned int index, unsigned int mask);
+void rc_for_all_reads_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata);
+void rc_for_all_writes_mask(struct rc_instruction * inst, rc_read_write_mask_fn cb, void * userdata);
 
 typedef void (*rc_remap_register_fn)(void * userdata, struct rc_instruction * inst,
                        rc_register_file * pfile, unsigned int * pindex);
@@ -60,4 +65,6 @@ void rc_dataflow_deadcode(struct radeon_compiler * c, rc_dataflow_mark_outputs_f
 void rc_dataflow_swizzles(struct radeon_compiler * c);
 /*@}*/
 
+void rc_optimize(struct radeon_compiler * c);
+
 #endif /* RADEON_DATAFLOW_H */
index d889612f4f4eb244b8b20c47316f49af642daf1c..863654cf6850651262f5cbfe72f6842063d25b56 100644 (file)
@@ -150,7 +150,7 @@ static void allocate_and_insert_proxies(struct emulate_branch_state * s,
        sap.Proxies = proxies;
 
        for(struct rc_instruction * inst = begin; inst != end; inst = inst->Next) {
-               rc_for_all_writes(inst, scan_write, &sap);
+               rc_for_all_writes_mask(inst, scan_write, &sap);
                rc_remap_registers(inst, remap_proxy_function, &sap);
        }
 
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c
new file mode 100644 (file)
index 0000000..21d7210
--- /dev/null
@@ -0,0 +1,446 @@
+/*
+ * Copyright (C) 2009 Nicolai Haehnle.
+ *
+ * All Rights Reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining
+ * a copy of this software and associated documentation files (the
+ * "Software"), to deal in the Software without restriction, including
+ * without limitation the rights to use, copy, modify, merge, publish,
+ * distribute, sublicense, and/or sell copies of the Software, and to
+ * permit persons to whom the Software is furnished to do so, subject to
+ * the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the
+ * next paragraph) shall be included in all copies or substantial
+ * portions of the Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+ * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
+ * IN NO EVENT SHALL THE COPYRIGHT OWNER(S) 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 "radeon_dataflow.h"
+
+#include "radeon_compiler.h"
+#include "radeon_swizzle.h"
+
+
+static struct rc_src_register chain_srcregs(struct rc_src_register outer, struct rc_src_register inner)
+{
+       struct rc_src_register combine;
+       combine.File = inner.File;
+       combine.Index = inner.Index;
+       combine.RelAddr = inner.RelAddr;
+       if (outer.Abs) {
+               combine.Abs = 1;
+               combine.Negate = outer.Negate;
+       } else {
+               combine.Abs = inner.Abs;
+               combine.Negate = 0;
+               for(unsigned int chan = 0; chan < 4; ++chan) {
+                       unsigned int swz = GET_SWZ(outer.Swizzle, chan);
+                       if (swz < 4)
+                               combine.Negate |= GET_BIT(inner.Negate, swz) << chan;
+               }
+               combine.Negate ^= outer.Negate;
+       }
+       combine.Swizzle = combine_swizzles(inner.Swizzle, outer.Swizzle);
+       return combine;
+}
+
+struct peephole_state {
+       struct radeon_compiler * C;
+       struct rc_instruction * Mov;
+       unsigned int Conflict:1;
+
+       /** Whether Mov's source has been clobbered */
+       unsigned int SourceClobbered:1;
+
+       /** Which components of Mov's destination register are still from that Mov? */
+       unsigned int MovMask:4;
+
+       /** Which components of Mov's destination register are clearly *not* from that Mov */
+       unsigned int DefinedMask:4;
+
+       /** Which components of Mov's source register are sourced */
+       unsigned int SourcedMask:4;
+
+       /** Branch depth beyond Mov; negative value indicates we left the Mov's block */
+       int BranchDepth;
+};
+
+static void peephole_scan_read(void * data, struct rc_instruction * inst,
+               rc_register_file file, unsigned int index, unsigned int mask)
+{
+       struct peephole_state * s = data;
+
+       if (file != RC_FILE_TEMPORARY || index != s->Mov->U.I.DstReg.Index)
+               return;
+
+       /* These instructions cannot read from the constants file.
+        * see radeonTransformTEX()
+        */
+       if(s->Mov->U.I.SrcReg[0].File != RC_FILE_TEMPORARY &&
+                       s->Mov->U.I.SrcReg[0].File != RC_FILE_INPUT &&
+                               (inst->U.I.Opcode == RC_OPCODE_TEX ||
+                               inst->U.I.Opcode == RC_OPCODE_TXB ||
+                               inst->U.I.Opcode == RC_OPCODE_TXP ||
+                               inst->U.I.Opcode == RC_OPCODE_KIL)){
+               s->Conflict = 1;
+               return;
+       }
+       if ((mask & s->MovMask) == mask) {
+               if (s->SourceClobbered) {
+                       s->Conflict = 1;
+               }
+       } else if ((mask & s->DefinedMask) == mask) {
+               /* read from something entirely written by other instruction: this is okay */
+       } else {
+               /* read from component combination that is not well-defined without
+                * the MOV: cannot remove it */
+               s->Conflict = 1;
+       }
+}
+
+static void peephole_scan_write(void * data, struct rc_instruction * inst,
+               rc_register_file file, unsigned int index, unsigned int mask)
+{
+       struct peephole_state * s = data;
+
+       if (s->BranchDepth < 0)
+               return;
+
+       if (file == s->Mov->U.I.DstReg.File && index == s->Mov->U.I.DstReg.Index) {
+               s->MovMask &= ~mask;
+               if (s->BranchDepth == 0)
+                       s->DefinedMask |= mask;
+               else
+                       s->DefinedMask &= ~mask;
+       }
+       if (file == s->Mov->U.I.SrcReg[0].File && index == s->Mov->U.I.SrcReg[0].Index) {
+               if (mask & s->SourcedMask)
+                       s->SourceClobbered = 1;
+       } else if (s->Mov->U.I.SrcReg[0].RelAddr && file == RC_FILE_ADDRESS) {
+               s->SourceClobbered = 1;
+       }
+}
+
+static void peephole(struct radeon_compiler * c, struct rc_instruction * inst_mov)
+{
+       struct peephole_state s;
+
+       if (inst_mov->U.I.DstReg.File != RC_FILE_TEMPORARY || inst_mov->U.I.WriteALUResult)
+               return;
+
+       memset(&s, 0, sizeof(s));
+       s.C = c;
+       s.Mov = inst_mov;
+       s.MovMask = inst_mov->U.I.DstReg.WriteMask;
+       s.DefinedMask = RC_MASK_XYZW & ~s.MovMask;
+
+       for(unsigned int chan = 0; chan < 4; ++chan) {
+               unsigned int swz = GET_SWZ(inst_mov->U.I.SrcReg[0].Swizzle, chan);
+               s.SourcedMask |= (1 << swz) & RC_MASK_XYZW;
+       }
+
+       /* 1st pass: Check whether all subsequent readers can be changed */
+       for(struct rc_instruction * inst = inst_mov->Next;
+           inst != &c->Program.Instructions;
+           inst = inst->Next) {
+               rc_for_all_reads_mask(inst, peephole_scan_read, &s);
+               rc_for_all_writes_mask(inst, peephole_scan_write, &s);
+               if (s.Conflict)
+                       return;
+
+               if (s.BranchDepth >= 0) {
+                       if (inst->U.I.Opcode == RC_OPCODE_IF) {
+                               s.BranchDepth++;
+                       } else if (inst->U.I.Opcode == RC_OPCODE_ENDIF) {
+                               s.BranchDepth--;
+                               if (s.BranchDepth < 0) {
+                                       s.DefinedMask &= ~s.MovMask;
+                                       s.MovMask = 0;
+                               }
+                       }
+               }
+       }
+
+       if (s.Conflict)
+               return;
+
+       /* 2nd pass: We can satisfy all readers, so switch them over all at once */
+       s.MovMask = inst_mov->U.I.DstReg.WriteMask;
+       s.BranchDepth = 0;
+
+       for(struct rc_instruction * inst = inst_mov->Next;
+           inst != &c->Program.Instructions;
+           inst = inst->Next) {
+               const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+               for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
+                       if (inst->U.I.SrcReg[src].File == RC_FILE_TEMPORARY &&
+                           inst->U.I.SrcReg[src].Index == s.Mov->U.I.DstReg.Index) {
+                               unsigned int refmask = 0;
+
+                               for(unsigned int chan = 0; chan < 4; ++chan) {
+                                       unsigned int swz = GET_SWZ(inst->U.I.SrcReg[src].Swizzle, chan);
+                                       refmask |= (1 << swz) & RC_MASK_XYZW;
+                               }
+
+                               if ((refmask & s.MovMask) == refmask)
+                                       inst->U.I.SrcReg[src] = chain_srcregs(inst->U.I.SrcReg[src], s.Mov->U.I.SrcReg[0]);
+                       }
+               }
+
+               if (opcode->HasDstReg) {
+                       if (inst->U.I.DstReg.File == RC_FILE_TEMPORARY &&
+                           inst->U.I.DstReg.Index == s.Mov->U.I.DstReg.Index) {
+                               s.MovMask &= ~inst->U.I.DstReg.WriteMask;
+                       }
+               }
+
+               if (s.BranchDepth >= 0) {
+                       if (inst->U.I.Opcode == RC_OPCODE_IF) {
+                               s.BranchDepth++;
+                       } else if (inst->U.I.Opcode == RC_OPCODE_ENDIF) {
+                               s.BranchDepth--;
+                               if (s.BranchDepth < 0)
+                                       break; /* no more readers after this point */
+                       }
+               }
+       }
+
+       /* Finally, remove the original MOV instruction */
+       rc_remove_instruction(inst_mov);
+}
+
+/**
+ * Check if a source register is actually always the same
+ * swizzle constant.
+ */
+static int is_src_uniform_constant(struct rc_src_register src,
+               rc_swizzle * pswz, unsigned int * pnegate)
+{
+       int have_used = 0;
+
+       if (src.File != RC_FILE_NONE) {
+               *pswz = 0;
+               return 0;
+       }
+
+       for(unsigned int chan = 0; chan < 4; ++chan) {
+               unsigned int swz = GET_SWZ(src.Swizzle, chan);
+               if (swz < 4) {
+                       *pswz = 0;
+                       return 0;
+               }
+               if (swz == RC_SWIZZLE_UNUSED)
+                       continue;
+
+               if (!have_used) {
+                       *pswz = swz;
+                       *pnegate = GET_BIT(src.Negate, chan);
+                       have_used = 1;
+               } else {
+                       if (swz != *pswz || *pnegate != GET_BIT(src.Negate, chan)) {
+                               *pswz = 0;
+                               return 0;
+                       }
+               }
+       }
+
+       return 1;
+}
+
+
+static void constant_folding_mad(struct rc_instruction * inst)
+{
+       rc_swizzle swz;
+       unsigned int negate;
+
+       if (is_src_uniform_constant(inst->U.I.SrcReg[2], &swz, &negate)) {
+               if (swz == RC_SWIZZLE_ZERO) {
+                       inst->U.I.Opcode = RC_OPCODE_MUL;
+                       return;
+               }
+       }
+
+       if (is_src_uniform_constant(inst->U.I.SrcReg[1], &swz, &negate)) {
+               if (swz == RC_SWIZZLE_ONE) {
+                       inst->U.I.Opcode = RC_OPCODE_ADD;
+                       if (negate)
+                               inst->U.I.SrcReg[0].Negate ^= RC_MASK_XYZW;
+                       inst->U.I.SrcReg[1] = inst->U.I.SrcReg[2];
+                       return;
+               } else if (swz == RC_SWIZZLE_ZERO) {
+                       inst->U.I.Opcode = RC_OPCODE_MOV;
+                       inst->U.I.SrcReg[0] = inst->U.I.SrcReg[2];
+                       return;
+               }
+       }
+
+       if (is_src_uniform_constant(inst->U.I.SrcReg[0], &swz, &negate)) {
+               if (swz == RC_SWIZZLE_ONE) {
+                       inst->U.I.Opcode = RC_OPCODE_ADD;
+                       if (negate)
+                               inst->U.I.SrcReg[1].Negate ^= RC_MASK_XYZW;
+                       inst->U.I.SrcReg[0] = inst->U.I.SrcReg[2];
+                       return;
+               } else if (swz == RC_SWIZZLE_ZERO) {
+                       inst->U.I.Opcode = RC_OPCODE_MOV;
+                       inst->U.I.SrcReg[0] = inst->U.I.SrcReg[2];
+                       return;
+               }
+       }
+}
+
+static void constant_folding_mul(struct rc_instruction * inst)
+{
+       rc_swizzle swz;
+       unsigned int negate;
+
+       if (is_src_uniform_constant(inst->U.I.SrcReg[0], &swz, &negate)) {
+               if (swz == RC_SWIZZLE_ONE) {
+                       inst->U.I.Opcode = RC_OPCODE_MOV;
+                       inst->U.I.SrcReg[0] = inst->U.I.SrcReg[1];
+                       if (negate)
+                               inst->U.I.SrcReg[0].Negate ^= RC_MASK_XYZW;
+                       return;
+               } else if (swz == RC_SWIZZLE_ZERO) {
+                       inst->U.I.Opcode = RC_OPCODE_MOV;
+                       inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_0000;
+                       return;
+               }
+       }
+
+       if (is_src_uniform_constant(inst->U.I.SrcReg[1], &swz, &negate)) {
+               if (swz == RC_SWIZZLE_ONE) {
+                       inst->U.I.Opcode = RC_OPCODE_MOV;
+                       if (negate)
+                               inst->U.I.SrcReg[0].Negate ^= RC_MASK_XYZW;
+                       return;
+               } else if (swz == RC_SWIZZLE_ZERO) {
+                       inst->U.I.Opcode = RC_OPCODE_MOV;
+                       inst->U.I.SrcReg[0].Swizzle = RC_SWIZZLE_0000;
+                       return;
+               }
+       }
+}
+
+static void constant_folding_add(struct rc_instruction * inst)
+{
+       rc_swizzle swz;
+       unsigned int negate;
+
+       if (is_src_uniform_constant(inst->U.I.SrcReg[0], &swz, &negate)) {
+               if (swz == RC_SWIZZLE_ZERO) {
+                       inst->U.I.Opcode = RC_OPCODE_MOV;
+                       inst->U.I.SrcReg[0] = inst->U.I.SrcReg[1];
+                       return;
+               }
+       }
+
+       if (is_src_uniform_constant(inst->U.I.SrcReg[1], &swz, &negate)) {
+               if (swz == RC_SWIZZLE_ZERO) {
+                       inst->U.I.Opcode = RC_OPCODE_MOV;
+                       return;
+               }
+       }
+}
+
+
+/**
+ * Replace 0.0, 1.0 and 0.5 immediate constants by their
+ * respective swizzles. Simplify instructions like ADD dst, src, 0;
+ */
+static void constant_folding(struct radeon_compiler * c, struct rc_instruction * inst)
+{
+       const struct rc_opcode_info * opcode = rc_get_opcode_info(inst->U.I.Opcode);
+
+       /* Replace 0.0, 1.0 and 0.5 immediates by their explicit swizzles */
+       for(unsigned int src = 0; src < opcode->NumSrcRegs; ++src) {
+               if (inst->U.I.SrcReg[src].File != RC_FILE_CONSTANT ||
+                   inst->U.I.SrcReg[src].RelAddr ||
+                   inst->U.I.SrcReg[src].Index >= c->Program.Constants.Count)
+                       continue;
+
+               struct rc_constant * constant =
+                       &c->Program.Constants.Constants[inst->U.I.SrcReg[src].Index];
+
+               if (constant->Type != RC_CONSTANT_IMMEDIATE)
+                       continue;
+
+               struct rc_src_register newsrc = inst->U.I.SrcReg[src];
+               int have_real_reference = 0;
+               for(unsigned int chan = 0; chan < 4; ++chan) {
+                       unsigned int swz = GET_SWZ(newsrc.Swizzle, chan);
+                       if (swz >= 4)
+                               continue;
+
+                       unsigned int newswz;
+                       float imm = constant->u.Immediate[swz];
+                       float baseimm = imm;
+                       if (imm < 0.0)
+                               baseimm = -baseimm;
+
+                       if (baseimm == 0.0) {
+                               newswz = RC_SWIZZLE_ZERO;
+                       } else if (baseimm == 1.0) {
+                               newswz = RC_SWIZZLE_ONE;
+                       } else if (baseimm == 0.5) {
+                               newswz = RC_SWIZZLE_HALF;
+                       } else {
+                               have_real_reference = 1;
+                               continue;
+                       }
+
+                       SET_SWZ(newsrc.Swizzle, chan, newswz);
+                       if (imm < 0.0 && !newsrc.Abs)
+                               newsrc.Negate ^= 1 << chan;
+               }
+
+               if (!have_real_reference) {
+                       newsrc.File = RC_FILE_NONE;
+                       newsrc.Index = 0;
+               }
+
+               /* don't make the swizzle worse */
+               if (!c->SwizzleCaps->IsNative(inst->U.I.Opcode, newsrc) &&
+                   c->SwizzleCaps->IsNative(inst->U.I.Opcode, inst->U.I.SrcReg[src]))
+                       continue;
+
+               inst->U.I.SrcReg[src] = newsrc;
+       }
+
+       /* Simplify instructions based on constants */
+       if (inst->U.I.Opcode == RC_OPCODE_MAD)
+               constant_folding_mad(inst);
+
+       /* note: MAD can simplify to MUL or ADD */
+       if (inst->U.I.Opcode == RC_OPCODE_MUL)
+               constant_folding_mul(inst);
+       else if (inst->U.I.Opcode == RC_OPCODE_ADD)
+               constant_folding_add(inst);
+}
+
+void rc_optimize(struct radeon_compiler * c)
+{
+       struct rc_instruction * inst = c->Program.Instructions.Next;
+       while(inst != &c->Program.Instructions) {
+               struct rc_instruction * cur = inst;
+               inst = inst->Next;
+
+               constant_folding(c, cur);
+
+               if (cur->U.I.Opcode == RC_OPCODE_MOV) {
+                       peephole(c, cur);
+                       /* cur may no longer be part of the program */
+               }
+       }
+}
index fdfee86701446721864be30df0b06ec561032ad7..8a912da461302f8da66753e58ff502b221d9a578 100644 (file)
@@ -159,7 +159,7 @@ static int try_add_live_intervals(struct regalloc_state * s,
 }
 
 static void scan_callback(void * data, struct rc_instruction * inst,
-               rc_register_file file, unsigned int index, unsigned int chan)
+               rc_register_file file, unsigned int index, unsigned int mask)
 {
        struct regalloc_state * s = data;
        struct register_info * reg;
@@ -191,8 +191,8 @@ static void compute_live_intervals(struct regalloc_state * s)
        for(struct rc_instruction * inst = s->C->Program.Instructions.Next;
            inst != &s->C->Program.Instructions;
            inst = inst->Next) {
-               rc_for_all_reads(inst, scan_callback, s);
-               rc_for_all_writes(inst, scan_callback, s);
+               rc_for_all_reads_mask(inst, scan_callback, s);
+               rc_for_all_writes_mask(inst, scan_callback, s);
        }
 }
 
index df67aafe02884e739f376e3e2e48ef1a9bd85770..a279549ff8940fdcaff9faf19aaa850c46901f05 100644 (file)
@@ -448,8 +448,8 @@ static void schedule_block(struct r300_fragment_program_compiler * c,
                 * counter-intuitive, to account for the case where an
                 * instruction writes to the same register as it reads
                 * from. */
-               rc_for_all_writes(inst, &scan_write, &s);
-               rc_for_all_reads(inst, &scan_read, &s);
+               rc_for_all_writes_chan(inst, &scan_write, &s);
+               rc_for_all_reads_chan(inst, &scan_read, &s);
 
                DBG("%i: Has %i dependencies\n", inst->IP, s.Current->NumDependencies);
 
index 42c08cd550537a0499487c5b031d613773557790..8336e58d554502cfbe4637f706d55a0563bccba5 100644 (file)
@@ -119,7 +119,7 @@ int radeonTransformTEX(
                        struct rc_instruction * inst_cmp;
                        unsigned tmp_texsample = rc_find_free_temporary(c);
                        unsigned tmp_sum = rc_find_free_temporary(c);
-                       unsigned tmp_recip_w;
+                       unsigned tmp_recip_w = 0;
                        int pass, fail, tex;
 
                        /* Save the output register. */
index 658ac9e40cf87d6366c4aeb3ef54d3d98d0de400..57a33292ed169aba5105e83069a0f3ccf5b67ade 100644 (file)
@@ -67,22 +67,27 @@ _mesa_dlopen(const char *libname, int flags)
 GenericFunc
 _mesa_dlsym(void *handle, const char *fname)
 {
+   union {
+      void *v;
+      GenericFunc f;
+   } u;
 #if defined(__blrts)
-   return (GenericFunc) NULL;
+   u.v = NULL;
 #elif defined(__DJGPP__)
    /* need '_' prefix on symbol names */
    char fname2[1000];
    fname2[0] = '_';
    strncpy(fname2 + 1, fname, 998);
    fname2[999] = 0;
-   return (GenericFunc) dlsym(handle, fname2);
+   u.v = dlsym(handle, fname2);
 #elif defined(_GNU_SOURCE)
-   return (GenericFunc) dlsym(handle, fname);
+   u.v = dlsym(handle, fname);
 #elif defined(__MINGW32__)
-   return (GenericFunc) GetProcAddress(handle, fname);
+   u.v = (void *) GetProcAddress(handle, fname);
 #else
-   return (GenericFunc) NULL;
+   u.v = NULL;
 #endif
+   return u.f;
 }
 
 
index 86d5b555e0fab6356be400f412ebbd24700b997d..c2ad5f238629243283ae3525b76648ef9f6faeac 100644 (file)
@@ -25,8 +25,6 @@
 #include "main/state.h"
 #include "main/imports.h"
 
-#include "main/dispatch.h"
-
 
 #if FEATURE_OES_draw_texture
 
index d2dcddddf27bdd6dac90432aa995df70ca1f553d..12d046b0754bbea29226c333b5f5196ed0e72e4d 100644 (file)
@@ -25,6 +25,7 @@
 #include "glheader.h"
 #include "context.h"
 #include "enable.h"
+#include "enums.h"
 #include "extensions.h"
 #include "get.h"
 #include "macros.h"
@@ -135,8 +136,8 @@ enum value_extra {
 
 struct value_desc {
    GLenum pname;
-   enum value_location location : 8;
-   enum value_type type : 8;
+   GLubyte location;  /**< enum value_location */
+   GLubyte type;      /**< enum value_type */
    int offset;
    const int *extra;
 };
@@ -1678,7 +1679,8 @@ check_extra(GLcontext *ctx, const char *func, const struct value_desc *d)
       }
 
    if (total > 0 && enabled == 0) {
-      _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, d->pname);
+      _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
+                  _mesa_lookup_enum_by_nr(d->pname));
       return GL_FALSE;
    }
 
@@ -1727,7 +1729,8 @@ find_value(const char *func, GLenum pname, void **p, union value *v)
       /* If the enum isn't valid, the hash walk ends with index 0,
        * which is the API mask entry at the beginning of values[]. */
       if (d->type == TYPE_API_MASK) {
-        _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
+        _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
+                     _mesa_lookup_enum_by_nr(pname));
         return &error_value;
       }
       hash += prime_step;
@@ -2256,10 +2259,12 @@ find_value_indexed(const char *func, GLenum pname, int index, union value *v)
    }
 
  invalid_enum:
-   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=0x%x)", func, pname);
+   _mesa_error(ctx, GL_INVALID_ENUM, "%s(pname=%s)", func,
+               _mesa_lookup_enum_by_nr(pname));
    return TYPE_INVALID;
  invalid_value:
-   _mesa_error(ctx, GL_INVALID_VALUE, "%s(pname=0x%x)", func, pname);
+   _mesa_error(ctx, GL_INVALID_VALUE, "%s(pname=%s)", func,
+               _mesa_lookup_enum_by_nr(pname));
    return TYPE_INVALID;
 }
 
index e5c08a641467db3e461b4f89bf778587657fa370..ca292aa0e89408136f46bf4496d98f86856395d6 100644 (file)
@@ -70,7 +70,8 @@ fpclassify(double x)
     }
 }
 
-#elif defined(__APPLE__) || defined(__CYGWIN__)
+#elif defined(__APPLE__) || defined(__CYGWIN__) || defined(__FreeBSD__) || \
+     (defined(__sun) && defined(__C99FEATURES__))
 
 /* fpclassify is available. */
 
index cd3dd9b38c1d58bde0fb83eab59d5be616c60927..050ebf02701684d58056c6fbae0f03a80340e83c 100644 (file)
@@ -190,7 +190,8 @@ _mesa_free_transform_feedback(GLcontext *ctx)
 
    /* Delete the default feedback object */
    assert(ctx->Driver.DeleteTransformFeedback);
-   ctx->Driver.DeleteTransformFeedback(ctx, ctx->TransformFeedback.DefaultObject);
+   ctx->Driver.DeleteTransformFeedback(ctx,
+                                       ctx->TransformFeedback.DefaultObject);
 
    ctx->TransformFeedback.CurrentObject = NULL;
 }
@@ -749,7 +750,7 @@ _mesa_BindTransformFeedback(GLenum target, GLuint name)
    if (ctx->TransformFeedback.CurrentObject->Active &&
        !ctx->TransformFeedback.CurrentObject->Paused) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glBindTransformFeedback(transform is active, or not paused)");
+              "glBindTransformFeedback(transform is active, or not paused)");
       return;
    }
 
@@ -844,7 +845,7 @@ _mesa_ResumeTransformFeedback(void)
 
    if (!obj->Active || !obj->Paused) {
       _mesa_error(ctx, GL_INVALID_OPERATION,
-                  "glPauseTransformFeedback(feedback not active or not paused)");
+               "glPauseTransformFeedback(feedback not active or not paused)");
       return;
    }
 
@@ -871,6 +872,11 @@ _mesa_DrawTransformFeedback(GLenum mode, GLuint name)
    struct gl_transform_feedback_object *obj =
       lookup_transform_feedback_object(ctx, name);
 
+   if (mode > GL_POLYGON) {
+      _mesa_error(ctx, GL_INVALID_ENUM,
+                  "glDrawTransformFeedback(mode=0x%x)", mode);
+      return;
+   }
    if (!obj) {
       _mesa_error(ctx, GL_INVALID_VALUE,
                   "glDrawTransformFeedback(name = %u)", name);
index 505c7bb46f96c0104db2ed2c79b185b963827204..f47f213ac8467a72c6ee338dfe8b80009f6eb031 100644 (file)
@@ -1753,7 +1753,8 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
          /* check that the sampler (tex unit index) is legal */
          if (texUnit >= ctx->Const.MaxTextureImageUnits) {
             _mesa_error(ctx, GL_INVALID_VALUE,
-                        "glUniform1(invalid sampler/tex unit index)");
+                        "glUniform1(invalid sampler/tex unit index for '%s')",
+                        param->Name);
             return;
          }
 
@@ -1801,7 +1802,8 @@ set_program_uniform(GLcontext *ctx, struct gl_program *program,
          /* non-array: count must be at most one; count == 0 is handled by the loop below */
          if (count > 1) {
             _mesa_error(ctx, GL_INVALID_OPERATION,
-                        "glUniform(uniform is not an array)");
+                        "glUniform(uniform '%s' is not an array)",
+                        param->Name);
             return;
          }
       }
@@ -1864,14 +1866,15 @@ _mesa_uniform(GLcontext *ctx, GLint location, GLsizei count,
       return;   /* The standard specifies this as a no-op */
 
    if (location < -1) {
-      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location)");
+      _mesa_error(ctx, GL_INVALID_OPERATION, "glUniform(location=%d)",
+                  location);
       return;
    }
 
    split_location_offset(&location, &offset);
 
    if (location < 0 || location >= (GLint) shProg->Uniforms->NumUniforms) {
-      _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location)");
+      _mesa_error(ctx, GL_INVALID_VALUE, "glUniform(location=%d)", location);
       return;
    }
 
index a8bd5db630431bcb945cfb0be5aa0aa19ee3ddc4..e423d9d8a51dbb9e9340ed98f1696d9a2dc54ced 100644 (file)
@@ -94,6 +94,9 @@ st_BeginQuery(GLcontext *ctx, struct gl_query_object *q)
    case GL_TRANSFORM_FEEDBACK_PRIMITIVES_WRITTEN:
       type = PIPE_QUERY_PRIMITIVES_EMITTED;
       break;
+   case GL_TIME_ELAPSED_EXT:
+      type = PIPE_QUERY_TIME_ELAPSED;
+      break;
    default:
       assert(0 && "unexpected query target in st_BeginQuery()");
       return;
index 12d3c99a3517b75cadd39675e42e9392f28ca77e..b8493dab93f0ad02fcc0b7c635fb59c08a9586c3 100644 (file)
@@ -46,6 +46,7 @@
 #include "st_debug.h"
 #include "st_context.h"
 #include "st_atom.h"
+#include "st_cb_bitmap.h"
 #include "st_cb_readpixels.h"
 #include "st_cb_fbo.h"
 
@@ -344,6 +345,8 @@ st_readpixels(GLcontext *ctx, GLint x, GLint y, GLsizei width, GLsizei height,
       return;
    }
 
+   st_flush_bitmap_cache(st);
+
    dest = _mesa_map_pbo_dest(ctx, &clippedPacking, dest);
    if (!dest)
       return;
index 0cd80fa59f7503dfc4f7ec291234755488c76f60..459e924cca39ddd919a52c4b9c004a6c78dc1082 100644 (file)
@@ -296,6 +296,9 @@ void st_init_extensions(struct st_context *st)
    if (screen->get_param(screen, PIPE_CAP_OCCLUSION_QUERY)) {
       ctx->Extensions.ARB_occlusion_query = GL_TRUE;
    }
+   if (screen->get_param(screen, PIPE_CAP_TIMER_QUERY)) {
+     ctx->Extensions.EXT_timer_query = GL_TRUE;
+   }
 
    if (screen->get_param(screen, PIPE_CAP_TEXTURE_SHADOW_MAP)) {
       ctx->Extensions.ARB_depth_texture = GL_TRUE;