summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/egl/drivers/Makefile.template2
-rw-r--r--src/egl/drivers/dri2/egl_dri2.c45
-rw-r--r--src/egl/drivers/glx/egl_glx.c2
-rw-r--r--src/egl/main/eglapi.c2
-rw-r--r--src/egl/main/eglconfig.c61
-rw-r--r--src/egl/main/eglconfig.h23
-rw-r--r--src/egl/main/egldisplay.h1
-rw-r--r--src/egl/main/eglmisc.c1
-rw-r--r--src/egl/main/eglsurface.c23
-rw-r--r--src/egl/main/eglsurface.h2
-rw-r--r--src/gallium/SConscript2
-rw-r--r--src/gallium/auxiliary/draw/draw_llvm.c55
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_debug.h13
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_flow.c2
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_format_soa.c15
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_init.c18
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c228
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.c44
-rw-r--r--src/gallium/auxiliary/gallivm/lp_bld_type.h4
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_exec.c2
-rw-r--r--src/gallium/auxiliary/tgsi/tgsi_ppc.c8
-rw-r--r--src/gallium/auxiliary/util/u_debug_symbol.c95
-rw-r--r--src/gallium/auxiliary/util/u_dump.h3
-rw-r--r--src/gallium/auxiliary/util/u_dump_defines.c45
-rw-r--r--src/gallium/auxiliary/util/u_format_pack.py3
-rwxr-xr-xsrc/gallium/auxiliary/util/u_format_parse.py2
-rw-r--r--src/gallium/auxiliary/util/u_format_srgb.py1
-rw-r--r--src/gallium/auxiliary/util/u_half.py8
-rw-r--r--src/gallium/docs/source/context.rst31
-rw-r--r--src/gallium/docs/source/screen.rst3
-rw-r--r--src/gallium/drivers/cell/ppu/cell_screen.c2
-rw-r--r--src/gallium/drivers/i915/i915_screen.c2
-rw-r--r--src/gallium/drivers/i965/brw_batchbuffer.c2
-rw-r--r--src/gallium/drivers/i965/brw_resource_texture.c2
-rw-r--r--src/gallium/drivers/i965/brw_screen.c2
-rw-r--r--src/gallium/drivers/llvmpipe/Makefile2
-rw-r--r--src/gallium/drivers/llvmpipe/lp_debug.h3
-rw-r--r--src/gallium/drivers/llvmpipe/lp_jit.c7
-rw-r--r--src/gallium/drivers/llvmpipe/lp_screen.c5
-rw-r--r--src/gallium/drivers/llvmpipe/lp_state_fs.c141
-rw-r--r--src/gallium/drivers/nv50/nv50_program.c23
-rw-r--r--src/gallium/drivers/nv50/nv50_push.c11
-rw-r--r--src/gallium/drivers/nv50/nv50_screen.c30
-rw-r--r--src/gallium/drivers/nv50/nv50_transfer.c4
-rw-r--r--src/gallium/drivers/nvfx/nvfx_screen.c40
-rw-r--r--src/gallium/drivers/r300/r300_context.c16
-rw-r--r--src/gallium/drivers/r300/r300_context.h20
-rw-r--r--src/gallium/drivers/r300/r300_debug.c82
-rw-r--r--src/gallium/drivers/r300/r300_emit.c27
-rw-r--r--src/gallium/drivers/r300/r300_flush.c42
-rw-r--r--src/gallium/drivers/r300/r300_query.c18
-rw-r--r--src/gallium/drivers/r300/r300_render.c37
-rw-r--r--src/gallium/drivers/r300/r300_screen.c1
-rw-r--r--src/gallium/drivers/r300/r300_screen.h30
-rw-r--r--src/gallium/drivers/r300/r300_state.c84
-rw-r--r--src/gallium/drivers/r300/r300_state_derived.c15
-rw-r--r--src/gallium/drivers/r300/r300_vs.c20
-rw-r--r--src/gallium/drivers/r300/r300_vs.h6
-rw-r--r--src/gallium/drivers/r300/r300_winsys.h9
-rw-r--r--src/gallium/drivers/rbug/rbug_screen.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_query.c35
-rw-r--r--src/gallium/drivers/softpipe/sp_screen.c2
-rw-r--r--src/gallium/drivers/softpipe/sp_texture.c4
-rw-r--r--src/gallium/drivers/svga/svga_screen.c2
-rw-r--r--src/gallium/drivers/svga/svga_swtnl.h1
-rw-r--r--src/gallium/drivers/trace/tr_dump.h1
-rw-r--r--src/gallium/include/pipe/p_defines.h4
-rw-r--r--src/gallium/include/pipe/p_screen.h1
-rw-r--r--src/gallium/include/state_tracker/dri1_api.h1
-rw-r--r--src/gallium/include/state_tracker/drm_api.h1
-rw-r--r--src/gallium/include/state_tracker/graw.h23
-rw-r--r--src/gallium/state_trackers/glx/xlib/glx_getproc.c1
-rw-r--r--src/gallium/state_trackers/xorg/xorg_crtc.c7
-rw-r--r--src/gallium/state_trackers/xorg/xorg_dri2.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_driver.c70
-rw-r--r--src/gallium/state_trackers/xorg/xorg_exa.c2
-rw-r--r--src/gallium/state_trackers/xorg/xorg_output.c59
-rw-r--r--src/gallium/state_trackers/xorg/xorg_renderer.c1
-rw-r--r--src/gallium/state_trackers/xorg/xorg_tracker.h5
-rw-r--r--src/gallium/targets/Makefile.egl2
-rw-r--r--src/gallium/targets/SConscript20
-rw-r--r--src/gallium/targets/graw-null/graw_null.c2
-rw-r--r--src/gallium/targets/graw-xlib/SConscript1
-rw-r--r--src/gallium/targets/graw-xlib/graw_util.c36
-rw-r--r--src/gallium/targets/graw-xlib/graw_xlib.c72
-rw-r--r--src/gallium/tests/graw/SConscript4
-rw-r--r--src/gallium/tests/graw/clear.c76
-rw-r--r--src/gallium/tests/graw/quad-tex.c404
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_buffer.h3
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_drm_buffer.c7
-rw-r--r--src/gallium/winsys/radeon/drm/radeon_r300.c8
-rw-r--r--src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c14
-rw-r--r--src/glx/dri2_glx.c21
-rw-r--r--src/mapi/es1api/Makefile2
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.c9
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_tri.c20
-rw-r--r--src/mesa/drivers/dri/i965/brw_clip_util.c36
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_context.h10
-rw-r--r--src/mesa/drivers/dri/i965/brw_defines.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_disasm.c30
-rw-r--r--src/mesa/drivers/dri/i965/brw_draw_upload.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu.h7
-rw-r--r--src/mesa/drivers/dri/i965/brw_eu_emit.c51
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs.c16
-rw-r--r--src/mesa/drivers/dri/i965/brw_gs_emit.c19
-rw-r--r--src/mesa/drivers/dri/i965/brw_queryobj.c27
-rw-r--r--src/mesa/drivers/dri/i965/brw_sf.c10
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.c23
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs.h2
-rw-r--r--src/mesa/drivers/dri/i965/brw_vs_emit.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_emit.c2
-rw-r--r--src/mesa/drivers/dri/i965/brw_wm_glsl.c2
-rw-r--r--src/mesa/drivers/dri/intel/intel_batchbuffer.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_blit.c3
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.c57
-rw-r--r--src/mesa/drivers/dri/intel/intel_context.h7
-rw-r--r--src/mesa/drivers/dri/intel/intel_screen.c13
-rw-r--r--src/mesa/drivers/dri/intel/intel_tex_format.c27
-rw-r--r--src/mesa/drivers/dri/r300/compiler/Makefile1
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c4
-rw-r--r--src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c4
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c106
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h13
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c2
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_optimize.c446
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c6
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c4
-rw-r--r--src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c2
-rw-r--r--src/mesa/main/dlopen.c15
-rw-r--r--src/mesa/main/drawtex.c2
-rw-r--r--src/mesa/main/get.c17
-rw-r--r--src/mesa/main/querymatrix.c3
-rw-r--r--src/mesa/main/transformfeedback.c12
-rw-r--r--src/mesa/shader/shader_api.c11
-rw-r--r--src/mesa/state_tracker/st_cb_queryobj.c3
-rw-r--r--src/mesa/state_tracker/st_cb_readpixels.c3
-rw-r--r--src/mesa/state_tracker/st_extensions.c3
139 files changed, 2502 insertions, 862 deletions
diff --git a/src/egl/drivers/Makefile.template b/src/egl/drivers/Makefile.template
index ca2f7d5b3a..08e82c65e9 100644
--- a/src/egl/drivers/Makefile.template
+++ b/src/egl/drivers/Makefile.template
@@ -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 $@
diff --git a/src/egl/drivers/dri2/egl_dri2.c b/src/egl/drivers/dri2/egl_dri2.c
index 82f409d294..eb9a6510ed 100644
--- a/src/egl/drivers/dri2/egl_dri2.c
+++ b/src/egl/drivers/dri2/egl_dri2.c
@@ -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
diff --git a/src/egl/drivers/glx/egl_glx.c b/src/egl/drivers/glx/egl_glx.c
index 3cbfebe488..e08ef5f222 100644
--- a/src/egl/drivers/glx/egl_glx.c
+++ b/src/egl/drivers/glx/egl_glx.c
@@ -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"
diff --git a/src/egl/main/eglapi.c b/src/egl/main/eglapi.c
index 923992da48..1a533e0880 100644
--- a/src/egl/main/eglapi.c
+++ b/src/egl/main/eglapi.c
@@ -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);
diff --git a/src/egl/main/eglconfig.c b/src/egl/main/eglconfig.c
index 47513a4edb..fa947d7688 100644
--- a/src/egl/main/eglconfig.c
+++ b/src/egl/main/eglconfig.c
@@ -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.
*/
diff --git a/src/egl/main/eglconfig.h b/src/egl/main/eglconfig.h
index ced060f779..ca63c40d3d 100644
--- a/src/egl/main/eglconfig.h
+++ b/src/egl/main/eglconfig.h
@@ -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;
+ }
}
diff --git a/src/egl/main/egldisplay.h b/src/egl/main/egldisplay.h
index 0b7f9d8303..42e305f91a 100644
--- a/src/egl/main/egldisplay.h
+++ b/src/egl/main/egldisplay.h
@@ -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];
};
diff --git a/src/egl/main/eglmisc.c b/src/egl/main/eglmisc.c
index 82ddb6cad9..e62a9e7de8 100644
--- a/src/egl/main/eglmisc.c
+++ b/src/egl/main/eglmisc.c
@@ -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
}
diff --git a/src/egl/main/eglsurface.c b/src/egl/main/eglsurface.c
index 8026a6314d..d46bdb0672 100644
--- a/src/egl/main/eglsurface.c
+++ b/src/egl/main/eglsurface.c
@@ -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;
diff --git a/src/egl/main/eglsurface.h b/src/egl/main/eglsurface.h
index 0a00035730..8f520dcdf6 100644
--- a/src/egl/main/eglsurface.h
+++ b/src/egl/main/eglsurface.h
@@ -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);
diff --git a/src/gallium/SConscript b/src/gallium/SConscript
index 02e6ea7a9f..e5e9578b5e 100644
--- a/src/gallium/SConscript
+++ b/src/gallium/SConscript
@@ -25,4 +25,4 @@ SConscript('targets/SConscript')
if platform != 'embedded':
SConscript('tests/unit/SConscript')
- SConscript('tests/graw/SConscript')
+ #SConscript('tests/graw/SConscript')
diff --git a/src/gallium/auxiliary/draw/draw_llvm.c b/src/gallium/auxiliary/draw/draw_llvm.c
index 05b187805b..7ea51621f7 100644
--- a/src/gallium/auxiliary/draw/draw_llvm.c
+++ b/src/gallium/auxiliary/draw/draw_llvm.c
@@ -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
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_debug.h b/src/gallium/auxiliary/gallivm/lp_bld_debug.h
index 1897acce79..858002b34f 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_debug.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_debug.h
@@ -36,6 +36,19 @@
#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, ...)
{
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_flow.c b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
index 560ce1de73..823a8ec7b7 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_flow.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_flow.c
@@ -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:
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
index a2b0298a1c..e1b94adc85 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_format_soa.c
@@ -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,
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_init.c b/src/gallium/auxiliary/gallivm/lp_bld_init.c
index 5067d0a164..bd080f397a 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_init.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_init.c
@@ -29,9 +29,23 @@
#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();
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
index aaf3360aa2..40ea94c493 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_tgsi_soa.c
@@ -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 );
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.c b/src/gallium/auxiliary/gallivm/lp_bld_type.c
index 37d278d237..aac3a57bc7 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.c
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.c
@@ -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;
@@ -239,6 +241,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.
*/
const char *
@@ -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));
}
diff --git a/src/gallium/auxiliary/gallivm/lp_bld_type.h b/src/gallium/auxiliary/gallivm/lp_bld_type.h
index b3f9e9175d..17819d4d32 100644
--- a/src/gallium/auxiliary/gallivm/lp_bld_type.h
+++ b/src/gallium/auxiliary/gallivm/lp_bld_type.h
@@ -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);
diff --git a/src/gallium/auxiliary/tgsi/tgsi_exec.c b/src/gallium/auxiliary/tgsi/tgsi_exec.c
index 1218242653..c15d970b57 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_exec.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_exec.c
@@ -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:
diff --git a/src/gallium/auxiliary/tgsi/tgsi_ppc.c b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
index ad553c71a5..3521847b61 100644
--- a/src/gallium/auxiliary/tgsi/tgsi_ppc.c
+++ b/src/gallium/auxiliary/tgsi/tgsi_ppc.c
@@ -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 */
diff --git a/src/gallium/auxiliary/util/u_debug_symbol.c b/src/gallium/auxiliary/util/u_debug_symbol.c
index 417d0cf04c..6e250575d6 100644
--- a/src/gallium/auxiliary/util/u_debug_symbol.c
+++ b/src/gallium/auxiliary/util/u_debug_symbol.c
@@ -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)
diff --git a/src/gallium/auxiliary/util/u_dump.h b/src/gallium/auxiliary/util/u_dump.h
index 68a6da804e..49536c0d59 100644
--- a/src/gallium/auxiliary/util/u_dump.h
+++ b/src/gallium/auxiliary/util/u_dump.h
@@ -71,6 +71,9 @@ 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);
const char *
diff --git a/src/gallium/auxiliary/util/u_dump_defines.c b/src/gallium/auxiliary/util/u_dump_defines.c
index c4ffc7ae35..692d4447c6 100644
--- a/src/gallium/auxiliary/util/u_dump_defines.c
+++ b/src/gallium/auxiliary/util/u_dump_defines.c
@@ -160,6 +160,49 @@ 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",
"PIPE_FUNC_LESS",
@@ -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",
diff --git a/src/gallium/auxiliary/util/u_format_pack.py b/src/gallium/auxiliary/util/u_format_pack.py
index 0c1bbc84c1..6d0016c0ad 100644
--- a/src/gallium/auxiliary/util/u_format_pack.py
+++ b/src/gallium/auxiliary/util/u_format_pack.py
@@ -37,9 +37,6 @@
'''
-import sys
-import math
-
from u_format_parse import *
diff --git a/src/gallium/auxiliary/util/u_format_parse.py b/src/gallium/auxiliary/util/u_format_parse.py
index 7076c676aa..ddb9f2443d 100755
--- a/src/gallium/auxiliary/util/u_format_parse.py
+++ b/src/gallium/auxiliary/util/u_format_parse.py
@@ -43,7 +43,7 @@ ZS = 'zs'
def is_pot(x):
- return (x & (x - 1)) == 0;
+ return (x & (x - 1)) == 0
VERY_LARGE = 99999999999999999999999
diff --git a/src/gallium/auxiliary/util/u_format_srgb.py b/src/gallium/auxiliary/util/u_format_srgb.py
index a4c76dc00b..3e8000f368 100644
--- a/src/gallium/auxiliary/util/u_format_srgb.py
+++ b/src/gallium/auxiliary/util/u_format_srgb.py
@@ -39,7 +39,6 @@
'''
-import sys
import math
diff --git a/src/gallium/auxiliary/util/u_half.py b/src/gallium/auxiliary/util/u_half.py
index 8007482e97..915cf3b927 100644
--- a/src/gallium/auxiliary/util/u_half.py
+++ b/src/gallium/auxiliary/util/u_half.py
@@ -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
diff --git a/src/gallium/docs/source/context.rst b/src/gallium/docs/source/context.rst
index c82e681a25..ec358e3454 100644
--- a/src/gallium/docs/source/context.rst
+++ b/src/gallium/docs/source/context.rst
@@ -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``.
diff --git a/src/gallium/docs/source/screen.rst b/src/gallium/docs/source/screen.rst
index 71b7aec35a..96257f93df 100644
--- a/src/gallium/docs/source/screen.rst
+++ b/src/gallium/docs/source/screen.rst
@@ -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.
diff --git a/src/gallium/drivers/cell/ppu/cell_screen.c b/src/gallium/drivers/cell/ppu/cell_screen.c
index 5af4eaa88b..750f0aa98a 100644
--- a/src/gallium/drivers/cell/ppu/cell_screen.c
+++ b/src/gallium/drivers/cell/ppu/cell_screen.c
@@ -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:
diff --git a/src/gallium/drivers/i915/i915_screen.c b/src/gallium/drivers/i915/i915_screen.c
index d196c779e4..7cf627d975 100644
--- a/src/gallium/drivers/i915/i915_screen.c
+++ b/src/gallium/drivers/i915/i915_screen.c
@@ -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:
diff --git a/src/gallium/drivers/i965/brw_batchbuffer.c b/src/gallium/drivers/i965/brw_batchbuffer.c
index 003b1fd5bf..8b3f46f2c1 100644
--- a/src/gallium/drivers/i965/brw_batchbuffer.c
+++ b/src/gallium/drivers/i965/brw_batchbuffer.c
@@ -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;
diff --git a/src/gallium/drivers/i965/brw_resource_texture.c b/src/gallium/drivers/i965/brw_resource_texture.c
index 07537fe44e..ca09d88fd1 100644
--- a/src/gallium/drivers/i965/brw_resource_texture.c
+++ b/src/gallium/drivers/i965/brw_resource_texture.c
@@ -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;
}
diff --git a/src/gallium/drivers/i965/brw_screen.c b/src/gallium/drivers/i965/brw_screen.c
index d242691f2d..1890b640e9 100644
--- a/src/gallium/drivers/i965/brw_screen.c
+++ b/src/gallium/drivers/i965/brw_screen.c
@@ -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:
diff --git a/src/gallium/drivers/llvmpipe/Makefile b/src/gallium/drivers/llvmpipe/Makefile
index 4ea367597e..526e85c82e 100644
--- a/src/gallium/drivers/llvmpipe/Makefile
+++ b/src/gallium/drivers/llvmpipe/Makefile
@@ -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
diff --git a/src/gallium/drivers/llvmpipe/lp_debug.h b/src/gallium/drivers/llvmpipe/lp_debug.h
index ee81814361..92fb2b3ee5 100644
--- a/src/gallium/drivers/llvmpipe/lp_debug.h
+++ b/src/gallium/drivers/llvmpipe/lp_debug.h
@@ -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
diff --git a/src/gallium/drivers/llvmpipe/lp_jit.c b/src/gallium/drivers/llvmpipe/lp_jit.c
index 243aea6c3a..23aa34ddec 100644
--- a/src/gallium/drivers/llvmpipe/lp_jit.c
+++ b/src/gallium/drivers/llvmpipe/lp_jit.c
@@ -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 */
diff --git a/src/gallium/drivers/llvmpipe/lp_screen.c b/src/gallium/drivers/llvmpipe/lp_screen.c
index 9d254853cb..22fbf381ae 100644
--- a/src/gallium/drivers/llvmpipe/lp_screen.c
+++ b/src/gallium/drivers/llvmpipe/lp_screen.c
@@ -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:
diff --git a/src/gallium/drivers/llvmpipe/lp_state_fs.c b/src/gallium/drivers/llvmpipe/lp_state_fs.c
index cc163ebd4f..9ef78e6bad 100644
--- a/src/gallium/drivers/llvmpipe/lp_state_fs.c
+++ b/src/gallium/drivers/llvmpipe/lp_state_fs.c
@@ -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);
}
diff --git a/src/gallium/drivers/nv50/nv50_program.c b/src/gallium/drivers/nv50/nv50_program.c
index 0156ff95ff..97f938e698 100644
--- a/src/gallium/drivers/nv50/nv50_program.c
+++ b/src/gallium/drivers/nv50/nv50_program.c
@@ -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);
}
diff --git a/src/gallium/drivers/nv50/nv50_push.c b/src/gallium/drivers/nv50/nv50_push.c
index 244242b843..c3ac804146 100644
--- a/src/gallium/drivers/nv50/nv50_push.c
+++ b/src/gallium/drivers/nv50/nv50_push.c
@@ -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);
diff --git a/src/gallium/drivers/nv50/nv50_screen.c b/src/gallium/drivers/nv50/nv50_screen.c
index ff3a7b2843..757f13b640 100644
--- a/src/gallium/drivers/nv50/nv50_screen.c
+++ b/src/gallium/drivers/nv50/nv50_screen.c
@@ -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;
diff --git a/src/gallium/drivers/nv50/nv50_transfer.c b/src/gallium/drivers/nv50/nv50_transfer.c
index c5581a6f9d..f973cf24b9 100644
--- a/src/gallium/drivers/nv50/nv50_transfer.c
+++ b/src/gallium/drivers/nv50/nv50_transfer.c
@@ -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);
}
diff --git a/src/gallium/drivers/nvfx/nvfx_screen.c b/src/gallium/drivers/nvfx/nvfx_screen.c
index 0ff25e54f7..a44f9e94d7 100644
--- a/src/gallium/drivers/nvfx/nvfx_screen.c
+++ b/src/gallium/drivers/nvfx/nvfx_screen.c
@@ -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;
diff --git a/src/gallium/drivers/r300/r300_context.c b/src/gallium/drivers/r300/r300_context.c
index 0444fdac7d..9837deaa5e 100644
--- a/src/gallium/drivers/r300/r300_context.c
+++ b/src/gallium/drivers/r300/r300_context.c
@@ -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);
diff --git a/src/gallium/drivers/r300/r300_context.h b/src/gallium/drivers/r300/r300_context.h
index 5ad448978b..e44906d009 100644
--- a/src/gallium/drivers/r300/r300_context.h
+++ b/src/gallium/drivers/r300/r300_context.h
@@ -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];
diff --git a/src/gallium/drivers/r300/r300_debug.c b/src/gallium/drivers/r300/r300_debug.c
index 8eb321fa08..85a1aa7b06 100644
--- a/src/gallium/drivers/r300/r300_debug.c
+++ b/src/gallium/drivers/r300/r300_debug.c
@@ -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");
+ }
+ }
+}
diff --git a/src/gallium/drivers/r300/r300_emit.c b/src/gallium/drivers/r300/r300_emit.c
index 568109cf96..7f7f2929cc 100644
--- a/src/gallium/drivers/r300/r300_emit.c
+++ b/src/gallium/drivers/r300/r300_emit.c
@@ -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);
diff --git a/src/gallium/drivers/r300/r300_flush.c b/src/gallium/drivers/r300/r300_flush.c
index e78c6a3624..d6876c1903 100644
--- a/src/gallium/drivers/r300/r300_flush.c
+++ b/src/gallium/drivers/r300/r300_flush.c
@@ -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)
diff --git a/src/gallium/drivers/r300/r300_query.c b/src/gallium/drivers/r300/r300_query.c
index 5c27796e89..6acbac2219 100644
--- a/src/gallium/drivers/r300/r300_query.c
+++ b/src/gallium/drivers/r300/r300_query.c
@@ -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;
}
diff --git a/src/gallium/drivers/r300/r300_render.c b/src/gallium/drivers/r300/r300_render.c
index 8795410efd..e1f61982be 100644
--- a/src/gallium/drivers/r300/r300_render.c
+++ b/src/gallium/drivers/r300/r300_render.c
@@ -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);
diff --git a/src/gallium/drivers/r300/r300_screen.c b/src/gallium/drivers/r300/r300_screen.c
index 8399f5df8e..640b3d3468 100644
--- a/src/gallium/drivers/r300/r300_screen.c
+++ b/src/gallium/drivers/r300/r300_screen.c
@@ -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:
diff --git a/src/gallium/drivers/r300/r300_screen.h b/src/gallium/drivers/r300/r300_screen.h
index d58aa138a7..29492024fe 100644
--- a/src/gallium/drivers/r300/r300_screen.h
+++ b/src/gallium/drivers/r300/r300_screen.h
@@ -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)
diff --git a/src/gallium/drivers/r300/r300_state.c b/src/gallium/drivers/r300/r300_state.c
index 006a34119b..11c10e2f2a 100644
--- a/src/gallium/drivers/r300/r300_state.c
+++ b/src/gallium/drivers/r300/r300_state.c
@@ -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)
diff --git a/src/gallium/drivers/r300/r300_state_derived.c b/src/gallium/drivers/r300/r300_state_derived.c
index c738899827..7583862a1a 100644
--- a/src/gallium/drivers/r300/r300_state_derived.c
+++ b/src/gallium/drivers/r300/r300_state_derived.c
@@ -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);
diff --git a/src/gallium/drivers/r300/r300_vs.c b/src/gallium/drivers/r300/r300_vs.c
index f3186431e1..59f89b3482 100644
--- a/src/gallium/drivers/r300/r300_vs.c
+++ b/src/gallium/drivers/r300/r300_vs.c
@@ -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;
diff --git a/src/gallium/drivers/r300/r300_vs.h b/src/gallium/drivers/r300/r300_vs.h
index 57b3fbca0b..31890d78ca 100644
--- a/src/gallium/drivers/r300/r300_vs.h
+++ b/src/gallium/drivers/r300/r300_vs.h
@@ -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 */
diff --git a/src/gallium/drivers/r300/r300_winsys.h b/src/gallium/drivers/r300/r300_winsys.h
index 1642981eaa..3d0413f90a 100644
--- a/src/gallium/drivers/r300/r300_winsys.h
+++ b/src/gallium/drivers/r300/r300_winsys.h
@@ -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,
diff --git a/src/gallium/drivers/rbug/rbug_screen.c b/src/gallium/drivers/rbug/rbug_screen.c
index 7d7b9247c3..2b60af2302 100644
--- a/src/gallium/drivers/rbug/rbug_screen.c
+++ b/src/gallium/drivers/rbug/rbug_screen.c
@@ -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)
diff --git a/src/gallium/drivers/softpipe/sp_query.c b/src/gallium/drivers/softpipe/sp_query.c
index 4ef5d9f7b1..b959af63af 100644
--- a/src/gallium/drivers/softpipe/sp_query.c
+++ b/src/gallium/drivers/softpipe/sp_query.c
@@ -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;
}
diff --git a/src/gallium/drivers/softpipe/sp_screen.c b/src/gallium/drivers/softpipe/sp_screen.c
index f874c3e60c..8c33efa198 100644
--- a/src/gallium/drivers/softpipe/sp_screen.c
+++ b/src/gallium/drivers/softpipe/sp_screen.c
@@ -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:
diff --git a/src/gallium/drivers/softpipe/sp_texture.c b/src/gallium/drivers/softpipe/sp_texture.c
index 7aa85559b2..4e6123fbd0 100644
--- a/src/gallium/drivers/softpipe/sp_texture.c
+++ b/src/gallium/drivers/softpipe/sp_texture.c
@@ -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);
diff --git a/src/gallium/drivers/svga/svga_screen.c b/src/gallium/drivers/svga/svga_screen.c
index 2c3c3f5220..bef22f41ae 100644
--- a/src/gallium/drivers/svga/svga_screen.c
+++ b/src/gallium/drivers/svga/svga_screen.c
@@ -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;
diff --git a/src/gallium/drivers/svga/svga_swtnl.h b/src/gallium/drivers/svga/svga_swtnl.h
index 8724690f7e..65c675f99c 100644
--- a/src/gallium/drivers/svga/svga_swtnl.h
+++ b/src/gallium/drivers/svga/svga_swtnl.h
@@ -30,7 +30,6 @@
struct svga_context;
struct pipe_context;
-struct pipe_buffer;
struct vbuf_render;
diff --git a/src/gallium/drivers/trace/tr_dump.h b/src/gallium/drivers/trace/tr_dump.h
index f21f72b0c7..74c5e83e9e 100644
--- a/src/gallium/drivers/trace/tr_dump.h
+++ b/src/gallium/drivers/trace/tr_dump.h
@@ -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;
diff --git a/src/gallium/include/pipe/p_defines.h b/src/gallium/include/pipe/p_defines.h
index bed480f75e..8201c29ac7 100644
--- a/src/gallium/include/pipe/p_defines.h
+++ b/src/gallium/include/pipe/p_defines.h
@@ -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,
diff --git a/src/gallium/include/pipe/p_screen.h b/src/gallium/include/pipe/p_screen.h
index 7195dc0396..0d9de48c90 100644
--- a/src/gallium/include/pipe/p_screen.h
+++ b/src/gallium/include/pipe/p_screen.h
@@ -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;
diff --git a/src/gallium/include/state_tracker/dri1_api.h b/src/gallium/include/state_tracker/dri1_api.h
index a48c5de5a0..0d702d9092 100644
--- a/src/gallium/include/state_tracker/dri1_api.h
+++ b/src/gallium/include/state_tracker/dri1_api.h
@@ -9,7 +9,6 @@
struct pipe_screen;
struct pipe_winsys;
-struct pipe_buffer;
struct pipe_context;
struct pipe_resource;
diff --git a/src/gallium/include/state_tracker/drm_api.h b/src/gallium/include/state_tracker/drm_api.h
index 3d8fdd86fc..8fd0995444 100644
--- a/src/gallium/include/state_tracker/drm_api.h
+++ b/src/gallium/include/state_tracker/drm_api.h
@@ -6,7 +6,6 @@
struct pipe_screen;
struct pipe_winsys;
-struct pipe_buffer;
struct pipe_context;
struct pipe_resource;
diff --git a/src/gallium/include/state_tracker/graw.h b/src/gallium/include/state_tracker/graw.h
index 385e4d7718..e5b298e03d 100644
--- a/src/gallium/include/state_tracker/graw.h
+++ b/src/gallium/include/state_tracker/graw.h
@@ -17,20 +17,27 @@
#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
diff --git a/src/gallium/state_trackers/glx/xlib/glx_getproc.c b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
index bd4a85caa0..26fcae78ec 100644
--- a/src/gallium/state_trackers/glx/xlib/glx_getproc.c
+++ b/src/gallium/state_trackers/glx/xlib/glx_getproc.c
@@ -34,7 +34,6 @@
#include <string.h>
#include "GL/glx.h"
#include "glapi/glapi.h"
-#include "pipe/p_compiler.h"
struct name_address_pair {
diff --git a/src/gallium/state_trackers/xorg/xorg_crtc.c b/src/gallium/state_trackers/xorg/xorg_crtc.c
index 669bd9edcf..f9022a9f93 100644
--- a/src/gallium/state_trackers/xorg/xorg_crtc.c
+++ b/src/gallium/state_trackers/xorg/xorg_crtc.c
@@ -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;
diff --git a/src/gallium/state_trackers/xorg/xorg_dri2.c b/src/gallium/state_trackers/xorg/xorg_dri2.c
index b90f9c908d..921b6900fc 100644
--- a/src/gallium/state_trackers/xorg/xorg_dri2.c
+++ b/src/gallium/state_trackers/xorg/xorg_dri2.c
@@ -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;
diff --git a/src/gallium/state_trackers/xorg/xorg_driver.c b/src/gallium/state_trackers/xorg/xorg_driver.c
index 3687ee0db4..44520b81b6 100644
--- a/src/gallium/state_trackers/xorg/xorg_driver.c
+++ b/src/gallium/state_trackers/xorg/xorg_driver.c
@@ -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);
diff --git a/src/gallium/state_trackers/xorg/xorg_exa.c b/src/gallium/state_trackers/xorg/xorg_exa.c
index 65be8c332a..31140f13bb 100644
--- a/src/gallium/state_trackers/xorg/xorg_exa.c
+++ b/src/gallium/state_trackers/xorg/xorg_exa.c
@@ -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;
diff --git a/src/gallium/state_trackers/xorg/xorg_output.c b/src/gallium/state_trackers/xorg/xorg_output.c
index 13c3fb97e3..056098f76b 100644
--- a/src/gallium/state_trackers/xorg/xorg_output.c
+++ b/src/gallium/state_trackers/xorg/xorg_output.c
@@ -51,6 +51,13 @@
#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: */
diff --git a/src/gallium/state_trackers/xorg/xorg_renderer.c b/src/gallium/state_trackers/xorg/xorg_renderer.c
index 583493116d..a9610a8678 100644
--- a/src/gallium/state_trackers/xorg/xorg_renderer.c
+++ b/src/gallium/state_trackers/xorg/xorg_renderer.c
@@ -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"
diff --git a/src/gallium/state_trackers/xorg/xorg_tracker.h b/src/gallium/state_trackers/xorg/xorg_tracker.h
index cb6773424a..65fbc3234b 100644
--- a/src/gallium/state_trackers/xorg/xorg_tracker.h
+++ b/src/gallium/state_trackers/xorg/xorg_tracker.h
@@ -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
diff --git a/src/gallium/targets/Makefile.egl b/src/gallium/targets/Makefile.egl
index f26ffb8ad4..4f8641e056 100644
--- a/src/gallium/targets/Makefile.egl
+++ b/src/gallium/targets/Makefile.egl
@@ -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
diff --git a/src/gallium/targets/SConscript b/src/gallium/targets/SConscript
index ca3e1ec132..9077cbf6a4 100644
--- a/src/gallium/targets/SConscript
+++ b/src/gallium/targets/SConscript
@@ -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'))
+
+
+
diff --git a/src/gallium/targets/graw-null/graw_null.c b/src/gallium/targets/graw-null/graw_null.c
index 293015bc6b..6965f5873e 100644
--- a/src/gallium/targets/graw-null/graw_null.c
+++ b/src/gallium/targets/graw-null/graw_null.c
@@ -18,8 +18,6 @@
#include "sw/sw_public.h"
#include "sw/sw.c"
-#include "state_tracker/graw.h"
-
#include <stdio.h>
diff --git a/src/gallium/targets/graw-xlib/SConscript b/src/gallium/targets/graw-xlib/SConscript
index ad84841922..40332fa4e1 100644
--- a/src/gallium/targets/graw-xlib/SConscript
+++ b/src/gallium/targets/graw-xlib/SConscript
@@ -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
index 0000000000..147532cdee
--- /dev/null
+++ b/src/gallium/targets/graw-xlib/graw_util.c
@@ -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);
+}
+
diff --git a/src/gallium/targets/graw-xlib/graw_xlib.c b/src/gallium/targets/graw-xlib/graw_xlib.c
index 21715c26fd..41120ba3c7 100644
--- a/src/gallium/targets/graw-xlib/graw_xlib.c
+++ b/src/gallium/targets/graw-xlib/graw_xlib.c
@@ -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"
@@ -27,21 +28,18 @@
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);
+ }
}
diff --git a/src/gallium/tests/graw/SConscript b/src/gallium/tests/graw/SConscript
index 8a92ac2c49..7eab973db3 100644
--- a/src/gallium/tests/graw/SConscript
+++ b/src/gallium/tests/graw/SConscript
@@ -12,7 +12,9 @@ env.Prepend(LIBPATH = [graw.dir])
env.Prepend(LIBS = ['graw'])
progs = [
- 'clear'
+ 'clear',
+ 'tri',
+ 'quad-tex',
]
for prog in progs:
diff --git a/src/gallium/tests/graw/clear.c b/src/gallium/tests/graw/clear.c
index 84dd780733..28c986eee6 100644
--- a/src/gallium/tests/graw/clear.c
+++ b/src/gallium/tests/graw/clear.c
@@ -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
index 0000000000..91b1cf49ed
--- /dev/null
+++ b/src/gallium/tests/graw/quad-tex.c
@@ -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;
+}
diff --git a/src/gallium/winsys/radeon/drm/radeon_buffer.h b/src/gallium/winsys/radeon/drm/radeon_buffer.h
index b48b6358e0..b9ecf9ded0 100644
--- a/src/gallium/winsys/radeon/drm/radeon_buffer.h
+++ b/src/gallium/winsys/radeon/drm/radeon_buffer.h
@@ -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
diff --git a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
index b836649892..a05205da88 100644
--- a/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
+++ b/src/gallium/winsys/radeon/drm/radeon_drm_buffer.c
@@ -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);
+}
diff --git a/src/gallium/winsys/radeon/drm/radeon_r300.c b/src/gallium/winsys/radeon/drm/radeon_r300.c
index 94cd5281e2..e188f7e7cc 100644
--- a/src/gallium/winsys/radeon/drm/radeon_r300.c
+++ b/src/gallium/winsys/radeon/drm/radeon_r300.c
@@ -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;
diff --git a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
index d4d4270eb8..b997abda9b 100644
--- a/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
+++ b/src/gallium/winsys/sw/wrapper/wrapper_sw_winsys.c
@@ -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;
diff --git a/src/glx/dri2_glx.c b/src/glx/dri2_glx.c
index eafb87c359..45959915b4 100644
--- a/src/glx/dri2_glx.c
+++ b/src/glx/dri2_glx.c
@@ -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;
}
diff --git a/src/mapi/es1api/Makefile b/src/mapi/es1api/Makefile
index 73be93e941..576ac5afdc 100644
--- a/src/mapi/es1api/Makefile
+++ b/src/mapi/es1api/Makefile
@@ -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),'
diff --git a/src/mesa/drivers/dri/i965/brw_clip.c b/src/mesa/drivers/dri/i965/brw_clip.c
index 029a16500b..49ef859e45 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.c
+++ b/src/mesa/drivers/dri/i965/brw_clip.c
@@ -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);
diff --git a/src/mesa/drivers/dri/i965/brw_clip.h b/src/mesa/drivers/dri/i965/brw_clip.h
index d71bac7f61..68222c6c27 100644
--- a/src/mesa/drivers/dri/i965/brw_clip.h
+++ b/src/mesa/drivers/dri/i965/brw_clip.h
@@ -114,8 +114,6 @@ struct brw_clip_compile {
GLboolean need_direction;
- GLuint last_mrf;
-
GLuint header_position_offset;
GLuint offset[VERT_ATTRIB_MAX];
};
diff --git a/src/mesa/drivers/dri/i965/brw_clip_tri.c b/src/mesa/drivers/dri/i965/brw_clip_tri.c
index b27fe654ca..916a99ea00 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_tri.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_tri.c
@@ -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);
diff --git a/src/mesa/drivers/dri/i965/brw_clip_util.c b/src/mesa/drivers/dri/i965/brw_clip_util.c
index 34a966a47a..2148bc8244 100644
--- a/src/mesa/drivers/dri/i965/brw_clip_util.c
+++ b/src/mesa/drivers/dri/i965/brw_clip_util.c
@@ -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);
diff --git a/src/mesa/drivers/dri/i965/brw_context.c b/src/mesa/drivers/dri/i965/brw_context.c
index 6b04ad9ec6..dc4bd5802d 100644
--- a/src/mesa/drivers/dri/i965/brw_context.c
+++ b/src/mesa/drivers/dri/i965/brw_context.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i965/brw_context.h b/src/mesa/drivers/dri/i965/brw_context.h
index 1f09651126..a97fcb0f4d 100644
--- a/src/mesa/drivers/dri/i965/brw_context.h
+++ b/src/mesa/drivers/dri/i965/brw_context.h
@@ -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
diff --git a/src/mesa/drivers/dri/i965/brw_defines.h b/src/mesa/drivers/dri/i965/brw_defines.h
index f26a13fc3c..2d3556b805 100644
--- a/src/mesa/drivers/dri/i965/brw_defines.h
+++ b/src/mesa/drivers/dri/i965/brw_defines.h
@@ -783,7 +783,7 @@
#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)
diff --git a/src/mesa/drivers/dri/i965/brw_disasm.c b/src/mesa/drivers/dri/i965/brw_disasm.c
index db3fc50a63..ff12daf497 100644
--- a/src/mesa/drivers/dri/i965/brw_disasm.c
+++ b/src/mesa/drivers/dri/i965/brw_disasm.c
@@ -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,
diff --git a/src/mesa/drivers/dri/i965/brw_draw_upload.c b/src/mesa/drivers/dri/i965/brw_draw_upload.c
index 8247faa36d..9cbff24863 100644
--- a/src/mesa/drivers/dri/i965/brw_draw_upload.c
+++ b/src/mesa/drivers/dri/i965/brw_draw_upload.c
@@ -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
};
diff --git a/src/mesa/drivers/dri/i965/brw_eu.h b/src/mesa/drivers/dri/i965/brw_eu.h
index 4f55158e8f..3a32ad26c1 100644
--- a/src/mesa/drivers/dri/i965/brw_eu.h
+++ b/src/mesa/drivers/dri/i965/brw_eu.h
@@ -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,
diff --git a/src/mesa/drivers/dri/i965/brw_eu_emit.c b/src/mesa/drivers/dri/i965/brw_eu_emit.c
index 785d382a00..175899b026 100644
--- a/src/mesa/drivers/dri/i965/brw_eu_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_eu_emit.c
@@ -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);
}
diff --git a/src/mesa/drivers/dri/i965/brw_gs.c b/src/mesa/drivers/dri/i965/brw_gs.c
index 4b13494ecf..94d93f3aa6 100644
--- a/src/mesa/drivers/dri/i965/brw_gs.c
+++ b/src/mesa/drivers/dri/i965/brw_gs.c
@@ -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 ||
diff --git a/src/mesa/drivers/dri/i965/brw_gs_emit.c b/src/mesa/drivers/dri/i965/brw_gs_emit.c
index dd7b057d62..99a6f6be11 100644
--- a/src/mesa/drivers/dri/i965/brw_gs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_gs_emit.c
@@ -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 */);
}
diff --git a/src/mesa/drivers/dri/i965/brw_queryobj.c b/src/mesa/drivers/dri/i965/brw_queryobj.c
index 6cce7e5089..3f47a68049 100644
--- a/src/mesa/drivers/dri/i965/brw_queryobj.c
+++ b/src/mesa/drivers/dri/i965/brw_queryobj.c
@@ -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;
}
diff --git a/src/mesa/drivers/dri/i965/brw_sf.c b/src/mesa/drivers/dri/i965/brw_sf.c
index 57d1c29ade..b0dd1ff3af 100644
--- a/src/mesa/drivers/dri/i965/brw_sf.c
+++ b/src/mesa/drivers/dri/i965/brw_sf.c
@@ -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;
diff --git a/src/mesa/drivers/dri/i965/brw_vs.c b/src/mesa/drivers/dri/i965/brw_vs.c
index 44b085e214..57ffb2d89e 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.c
+++ b/src/mesa/drivers/dri/i965/brw_vs.c
@@ -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
},
diff --git a/src/mesa/drivers/dri/i965/brw_vs.h b/src/mesa/drivers/dri/i965/brw_vs.h
index 95e0501b1e..6493744f3e 100644
--- a/src/mesa/drivers/dri/i965/brw_vs.h
+++ b/src/mesa/drivers/dri/i965/brw_vs.h
@@ -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;
};
diff --git a/src/mesa/drivers/dri/i965/brw_vs_emit.c b/src/mesa/drivers/dri/i965/brw_vs_emit.c
index dc6ab81c4a..0b44deeb63 100644
--- a/src/mesa/drivers/dri/i965/brw_vs_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_vs_emit.c
@@ -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");
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_emit.c b/src/mesa/drivers/dri/i965/brw_wm_emit.c
index 375e795391..323cfac8fa 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_emit.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_emit.c
@@ -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");
}
}
diff --git a/src/mesa/drivers/dri/i965/brw_wm_glsl.c b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
index 88b885cb94..fe3c89b721 100644
--- a/src/mesa/drivers/dri/i965/brw_wm_glsl.c
+++ b/src/mesa/drivers/dri/i965/brw_wm_glsl.c
@@ -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");
}
}
diff --git a/src/mesa/drivers/dri/intel/intel_batchbuffer.c b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
index 9768b0deee..ca8e344836 100644
--- a/src/mesa/drivers/dri/intel/intel_batchbuffer.c
+++ b/src/mesa/drivers/dri/intel/intel_batchbuffer.c
@@ -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);
}
diff --git a/src/mesa/drivers/dri/intel/intel_blit.c b/src/mesa/drivers/dri/intel/intel_blit.c
index 7d9f302dca..a590c799ad 100644
--- a/src/mesa/drivers/dri/intel/intel_blit.c
+++ b/src/mesa/drivers/dri/intel/intel_blit.c
@@ -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
diff --git a/src/mesa/drivers/dri/intel/intel_context.c b/src/mesa/drivers/dri/intel/intel_context.c
index 0369942b39..05d4998654 100644
--- a/src/mesa/drivers/dri/intel/intel_context.c
+++ b/src/mesa/drivers/dri/intel/intel_context.c
@@ -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);
diff --git a/src/mesa/drivers/dri/intel/intel_context.h b/src/mesa/drivers/dri/intel/intel_context.h
index db244e5872..04d5fc92a2 100644
--- a/src/mesa/drivers/dri/intel/intel_context.h
+++ b/src/mesa/drivers/dri/intel/intel_context.h
@@ -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) \
diff --git a/src/mesa/drivers/dri/intel/intel_screen.c b/src/mesa/drivers/dri/intel/intel_screen.c
index 3aed253e24..15a465c640 100644
--- a/src/mesa/drivers/dri/intel/intel_screen.c
+++ b/src/mesa/drivers/dri/intel/intel_screen.c
@@ -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 *
diff --git a/src/mesa/drivers/dri/intel/intel_tex_format.c b/src/mesa/drivers/dri/intel/intel_tex_format.c
index 7be5231eae..610a169beb 100644
--- a/src/mesa/drivers/dri/intel/intel_tex_format.c
+++ b/src/mesa/drivers/dri/intel/intel_tex_format.c
@@ -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;
}
diff --git a/src/mesa/drivers/dri/r300/compiler/Makefile b/src/mesa/drivers/dri/r300/compiler/Makefile
index e432afc3d4..34d22b4559 100644
--- a/src/mesa/drivers/dri/r300/compiler/Makefile
+++ b/src/mesa/drivers/dri/r300/compiler/Makefile
@@ -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 \
diff --git a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
index cfa48a59e3..5d5de2f1b2 100644
--- a/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
+++ b/src/mesa/drivers/dri/r300/compiler/r300_fragprog_swizzle.c
@@ -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;
}
}
diff --git a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
index 25bf373b6f..3e88ccbc46 100644
--- a/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
+++ b/src/mesa/drivers/dri/r300/compiler/r3xx_fragprog.c
@@ -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;
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
index 16e2f3a218..0e6c62541f 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.c
@@ -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)
{
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
index 62cda20eea..60a6e192a9 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_dataflow.h
@@ -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 */
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
index d889612f4f..863654cf68 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_emulate_branches.c
@@ -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
index 0000000000..21d7210888
--- /dev/null
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_optimize.c
@@ -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 */
+ }
+ }
+}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
index fdfee86701..8a912da461 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_regalloc.c
@@ -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);
}
}
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
index df67aafe02..a279549ff8 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_pair_schedule.c
@@ -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);
diff --git a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
index 42c08cd550..8336e58d55 100644
--- a/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
+++ b/src/mesa/drivers/dri/r300/compiler/radeon_program_tex.c
@@ -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. */
diff --git a/src/mesa/main/dlopen.c b/src/mesa/main/dlopen.c
index 658ac9e40c..57a33292ed 100644
--- a/src/mesa/main/dlopen.c
+++ b/src/mesa/main/dlopen.c
@@ -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;
}
diff --git a/src/mesa/main/drawtex.c b/src/mesa/main/drawtex.c
index 86d5b555e0..c2ad5f2386 100644
--- a/src/mesa/main/drawtex.c
+++ b/src/mesa/main/drawtex.c
@@ -25,8 +25,6 @@
#include "main/state.h"
#include "main/imports.h"
-#include "main/dispatch.h"
-
#if FEATURE_OES_draw_texture
diff --git a/src/mesa/main/get.c b/src/mesa/main/get.c
index d2dcddddf2..12d046b075 100644
--- a/src/mesa/main/get.c
+++ b/src/mesa/main/get.c
@@ -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;
}
diff --git a/src/mesa/main/querymatrix.c b/src/mesa/main/querymatrix.c
index e5c08a6414..ca292aa0e8 100644
--- a/src/mesa/main/querymatrix.c
+++ b/src/mesa/main/querymatrix.c
@@ -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. */
diff --git a/src/mesa/main/transformfeedback.c b/src/mesa/main/transformfeedback.c
index cd3dd9b38c..050ebf0270 100644
--- a/src/mesa/main/transformfeedback.c
+++ b/src/mesa/main/transformfeedback.c
@@ -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);
diff --git a/src/mesa/shader/shader_api.c b/src/mesa/shader/shader_api.c
index 505c7bb46f..f47f213ac8 100644
--- a/src/mesa/shader/shader_api.c
+++ b/src/mesa/shader/shader_api.c
@@ -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;
}
diff --git a/src/mesa/state_tracker/st_cb_queryobj.c b/src/mesa/state_tracker/st_cb_queryobj.c
index a8bd5db630..e423d9d8a5 100644
--- a/src/mesa/state_tracker/st_cb_queryobj.c
+++ b/src/mesa/state_tracker/st_cb_queryobj.c
@@ -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;
diff --git a/src/mesa/state_tracker/st_cb_readpixels.c b/src/mesa/state_tracker/st_cb_readpixels.c
index 12d3c99a35..b8493dab93 100644
--- a/src/mesa/state_tracker/st_cb_readpixels.c
+++ b/src/mesa/state_tracker/st_cb_readpixels.c
@@ -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;
diff --git a/src/mesa/state_tracker/st_extensions.c b/src/mesa/state_tracker/st_extensions.c
index 0cd80fa59f..459e924cca 100644
--- a/src/mesa/state_tracker/st_extensions.c
+++ b/src/mesa/state_tracker/st_extensions.c
@@ -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;